對js中的一些基本的很重要的概念做一些總結,對進一步學習js很重。
一、this
JavaScript 中的 this 總是指向一個對象,而具體指向那個對象是在運行時基於函數的執行環境動態綁定的,而非函數聲明時的環境
實際應用中 this 的指向大致可以分為以下 4 中:
1. 作為對象的方法調用
2. 作為普通函數掉用
3. 構造器調用
4. Function.prototype.call 或 Function.prototype.apply 調用, 可以動態地改變出入函數的 this
1. 作為對象的方法調用時, this 指向該對象
1 var obj = { 2 a: 1, 3 getA: function(){ 4 console.log( this == obj ); // true 5 console.log( this.a ); // 1 6 } 7 }; 8 obj.getA();
2. 作為普通函數掉用,this 總是指向全局對象 window
1 console.log(this); // Windows 2 3 window.name = "globalName"; 4 var getName = function() { 5 return this.name; 6 } 7 8 console.log( getName() ); // globalName
3. 構造器調用, 當用 new 運算符調用函數時,該函數總是會返回一個對象,通常情況下,構造函數里的 this 就指向返回的這個對象
1 var MyClass = function(){ 2 this.name = "class"; 3 } 4 var obj = new MyClass(); 5 console.log( obj.name ); // class
如果使用 new 調用構造器時,構造器顯式地返回了一個 object 類型的對象,那么此次運算結果最終會返回這個對象,而不是我么之前期待的 this
1 var MyClass = function(){ 2 this.name = "class"; 3 return { 4 name: "other" 5 } 6 } 7 var obj = new MyClass(); 8 console.log(obj.name); // other
二、 call 和 apply
他們的作用一模一樣,區別僅在於傳入參數形式的不同。
apply 接收兩個參數,第一個參數指定了函數體內 this 對象的指向,第二個參數為一個帶下標的集合,這個集合可以是數組,也可以是類數組,apply 方法把這個集合中的元素作為參數傳入被調用的函數。
call 傳入的參數不固定,跟 apply 相同的是,第一個參數也代表函數體內的 this 指向,從第二個參數開始往后,每個參數被依次傳入函數
1 var func = function(a, b, c){ 2 console.log([a, b, c]); 3 } 4 //傳入的第一個參數為 null ,函數體內的 this 會指向默認的宿主對象,在瀏覽器中則是 window 5 func.apply(null, [1, 2, 3]); // 輸出:[ 1, 2, 3 ] 6 7 func.call(null, 1, 2, 3); // 輸出:[ 1, 2, 3 ]
call 和 apply 的用途:
1. 改變 this 指向
1 var obj1 = { 2 name: "obj1" 3 }; 4 var obj2 = { 5 name: "obj2" 6 }; 7 8 window.name = "window"; 9 10 var getName = function(){ 11 console.log( this.name ); 12 } 13 14 getName(); // window 15 getName.call( obj1 ); // obj1 16 getName.call( obj2 ); // obj2
當執行 getName.call( obj1 ) 這句代碼時, getName 函數體內的 this 就指向 obj1 對象,所以此處的
var getName = function(){ console.log( this.name ); }
實際上相當於
var getName = function(){ console.log( obj1.name ); }
2. 用來模擬 Function.prototype.bind 指定函數內部的 this 指向
3. 借用其他對象的方法, 可以模擬實現繼承
1 var A = function(name){ 2 this.name = name; 3 } 4 var B = function(){ 5 A.apply( this, arguments); 6 } 7 B.prototype.getName = function(){ 8 return this.name; 9 } 10 11 var b = new B("2B鉛筆"); 12 console.log( b.getName() ); // 輸出: 2B鉛筆
借用 Array.prototype 對象上的方法,對參數列表 arguments 這個類數組對象,進行數組對象方法的調用
1 (function(){ 2 Array.prototype.push.call( arguments, 3); 3 console.log( arguments ); // 輸出: [1, 2, 3] 4 })(1, 2);
三、ECMAScript 5 中的 bind() 方法可以將函數綁定到一個對象上
1 function f(y) {return this.x + y}; 2 var o = { x: 1}; 3 var g = f.bind(o); 4 g(2); // 3