国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript中arguments和this對象用法分析

2019-11-19 13:19:28
字體:
來源:轉載
供稿:網友

本文實例講述了JavaScript中arguments和this對象用法。分享給大家供大家參考,具體如下:

在函數內部有兩個特殊的對象 : arguments和this。

1、arguments對象

js函數不介意定義多少參數,也不在乎傳遞進來多少參數,也就是說,即使定義的函數只接收2個參數,在調用時候也未必傳遞2個參數,因為js的函數參數在內部使用一個數組表示的,在函數體內可以通過arguments對象訪問此參數數組。因此,js函數可以不顯式地使用命名參數。

當函數被調用時,傳入的參數將保存在arguments類數組對象中,通過arguments可以訪問所有該函數被調用時傳遞給它的參數列表。

arguments是一個類數組對象,因為arguments可以通過方括號語法訪問每一個元素,且擁有一個length屬性,但它缺少所有的數組方法,因此并不是一個真正的數組。

使用arguments可以實現一個求和函數:

function add() { var sum = 0; for (var i = 0, len = arguments.length; i < len; i++)  sum += arguments[i]; return sum;}

雖然arguments的主要用途是保存函數參數,但這個對象還有一個callee屬性,該屬性是一個指針,指向擁有這個arguments對象的函數。

使用arguments.callee屬性可以實現一個階乘函數:

function factorial(num) {  if (num <= 1)  return 1;  else  return num * arguments.callee(num - 1);}

注意:

在嚴格模式下,不能使用arguments.callee屬性,也不能對arguments對象賦值,更不能用arguments對象跟蹤參數的變化。

可以使用命名函數表達式來達成同樣的效果:

var factorial = (function func(num) { if (num <= 1)  return 1; else  return num * func(num - 1);));

由于js函數沒有簽名(定義接受的參數的類型和數量),js函數沒有重載,對于同名函數,后定義的函數會覆蓋先定義的函數。當然,通過檢查傳入的參數的類型和數量并做出不同的反應,可以模仿方法的重載。

2、this對象

與別的語言不同,JavaScript的this總是指向一個對象,而具體指向哪個對象是在運行時基于函數的執行環境動態綁定的,而非函數被聲明時的環境。

  • this是執行上下文的一個屬性,其值在進入上下文時確定,且在上下文運行期間永久不變。
  • this 是動態綁定的,即在運行期綁定。
  • this可以是全局對象,當前對象或任意對象,取決于函數的調用方式。函數的調用方式有以下幾種:作為普通函數調用,作為對象方法調用,作為構造函數調用,使用call()apply()調用。

(1)作為普通函數調用

當函數不作為對象的屬性被調用,即直接被調用時,this會被綁定到全局對象。在瀏覽器的JavaScript里,該全局對象是window對象。

var name = "Alice";function getName (name) { return this.name;}alert(getName()); // 輸出:Alicevar name = "Alice";var obj = { name: 'Bruce', getName: function(name) {  return this.name; }};var getName = obj.getName();alert(getName()); // 輸出:Alice

以上兩個實例中,this都被綁定到了全局對象。

var firstname = "A";var lastname = "B";var person = { firstname : "Alice", lastname : "Bruce", setName : function(firstname, lastname) {  var setFirstName = function(firstname) {   this.firstname = firstname;  };  var setLastName = function(lastname) {   this.lastname = lastname;  };  setFirstName(firstname);  setLastName(lastname); }};person.setName("Cindy", "David");alert(firstname);//Cindyalert(lastname);//Davidalert(person.firstname);//Alicealert(person.lastname);//Bruce

問題:在函數內部定義的函數,this也可能會指向全局,而希望的是內部函數的this綁定到外部函數對應的對象上。

原因:內部函數永遠不可能直接訪問外部函數中的this變量。

解決:在外部函數體中,要進入內部函數時,將this保存到一個變量中,再運用該變量。

var firstname = "A";var lastname = "B";var person = { firstname: "Alice", lastname: "Bruce", setName: function(firstname, lastname) {  var that = this;  var setFirstName = function(firstname) {   that.firstname= firstname;  };  var setLastName = function(lastname) {   that.lastname= lastname;  };  setFirstName(firstname);  setLastName(lastname); }};person.setName("Cindy", "David");alert(firstname);//Aalert(lastname);//Balert(person.firstname);//Cindyalert(person.lastname);//David

(2)作為對象方法調用

當函數作為對象方法調用時,this會被綁定到當前對象。

var firstname = "A";var lastname = "B";var person = { firstname : "Alice", lastname : "Bruce", setName : function(firstname, lastname) {  this.firstname = this.firstname + firstname;  this.lastname = this.lastname + lastname; }};person.setName("Cindy", "David");alert(firstname);//Aalert(lastname);//Balert(person.firstname);//AliceCindyalert(person.lastname);//BruceDavid

this被綁定到了當前對象,即person對象。

(3)作為構造函數調用

JavaScript中沒有類,但可以從構造器中創建對象,同時也提供了new運算符,使得構造器看起來更像一個類。

利用構造函數創建新對象時,可以將this來指向新創建的對象,避免函數中的this指向全局。

var name = "Alice";function Person(name) { this.name = name;}var person = new Person("Bruce");alert(name);//Alicealert(person.name);//Bruce

利用構造函數創建新對象person,this指向了person。

用new調用構造器時。還要注意一個問題,若構造器顯式返回了一個object類型的對象,構造器返回的結果將是這個對象,而不是this。

function Person() { this.name = "Alice" return {  name: "Bruce" }}var person = new Person();alert(person.name);//Bruce

(4)call()和apply()調用

call()apply()切換函數執行的上下文環境,即this綁定的對象;this指向的是apply()call()中的第一個參數。

function Person(name) { this.name = name; this.setName = function(name) {  this.name = name; }}var person1 = new Person("Alice");var person2 = {"name": "Bruce"};alert("person1: " + person1.name); // person1: Aliceperson1.setName("David");alert("person1: " + person1.name); // person1: Davidalert("person2: " + person2.name); // person2: Bruceperson1.setName.apply(person2, ["Cindy"]);alert("person2: " + person2.name); // person2: Cindy

apply()將person1的方法應用到person2上,this也被綁定到person2上。

3、this優先級

(1)函數是否在new中調用,是的話this綁定到新創建的對象。

(2)函數是否通過call、apply調用,是的話this綁定到指定對象。

(3)函數是否在某個上下文對象中調用,是的話this綁定到該上下文對象。

(4)若都不是,使用默認綁定,若在嚴格模式下,綁定到undefined,否則綁定到全局對象。

4、this丟失的問題

eg1:

var person = { name: "Alice", getName: function() {  return this.name; }};alert(person.getName()); // Alicevar getName = person.getName;alert(getName()); // undefined

當調用person.getName()時,getName()方法是作為person對象的屬性被調用的,因此this指向person對象;

當用另一個變量getName來引用person.getName,并調用getName()時,是作為普通函數被調用,因此this指向全局window。

eg2:

<div id="div">正確的方式</div><script> var getId = function(id) {  return document.getElementById(id); }; alert(getId('div').innerText);</script><div id="div">錯誤的方式</div><script> var getId = document.getElementById; alert(getId('div').innerText); // 拋出異常</script>

問題:第一段調用正常,但第二段調用會拋出異常。

原因:許多引擎的document.getElementById()方法的內部實現中需要用到this,this本來期望指向的是document,當第一段代碼在getElementById()方法作為document對象的屬性被調用時,方法內部的this確實是指向document的,而第二段代碼中,用getId來引用document.getElementById之后,再調用getId,此時就成了普通函數調用,函數內部的this指向了window,而不是原來的document。

解決:利用apply把document當作this傳入getId函數,修正this。

<div id="div">修正的方式</div><script> document.getElementById = (function(func) {  return function() {   return func.apply(document, arguments);  }; })(document.getElementById); var getId = document.getElementById; alert(getId('div').innerText); // 拋出異常</script>

更多關于JavaScript相關內容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript常用函數技巧匯總》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永丰县| 重庆市| 城市| 怀宁县| 河东区| 西丰县| 商水县| 开鲁县| 额尔古纳市| 新平| 光泽县| 兰考县| 宁津县| 封开县| 绩溪县| 二连浩特市| 万安县| 阿巴嘎旗| 吴忠市| 资溪县| 吐鲁番市| 鄄城县| 和政县| 涞源县| 海伦市| 兰考县| 天长市| 巴林右旗| 闽侯县| 河间市| 水城县| 孝感市| 鹤山市| 潍坊市| 司法| 三门县| 海门市| 新蔡县| 无锡市| 临沂市| 徐汇区|