標籤:
Javascript使用函數apply擴充環境對象
通過執行個體對象作為參數傳入調用建構函式對象的apply方法,
以使執行個體對象作為環境對象在作為一個普通函數的建構函式中執行,
建構函式的屬性會覆蓋到執行個體對象上,從而實現執行個體對象的屬性擴充。
1.函數對象的apply和call傳入參數
var tag = "global"; function say(){ for(var args = "", i = 0; i < arguments.length; ++i) args += arguments[i] + ","; console.log(this.tag + ": " + args); } var obj = { tag: "obj", sayObj: function(){ console.log(this.tag); } }; /**apply接受環境對象和數組參數;call接受環境對象和打散的數組參數*/ say.apply(obj, [1, 3, 7, 11]);//obj: 1,3,7,11, say.call(obj, 2, 4, [8, 14]);//obj: 2,4,8,14, say();//global /**obj對象內部的this還是指向Global的,對象內部的函數的this才會指向這個對象*/ //obj.say(); //Uncaught TypeError: obj.say is not a function obj.sayObj(); //obj
2.只有函數對象才有apply方法調用
var x = { name: "x", sayX: function(){ console.log("x:" + this.name); } }; var y = { name: "y" }; /**調用的x對象的的sayX列印出x:x*/ x.sayX(); //x:x /**普通的對象x上並沒有apply方法以供調用*/ //x.apply(y); //error: x.apply is not a function /**函數x.sayX在y對象的環境中執行,列印出x:y*/ x.sayX.apply(y); //x:y /**在y中擴充的是sayX函數下的屬性,而不是sayX本身*/ //y.sayX(); //error: y.sayX is not a function
3.在函數對象上使用apply擴充其對象屬性
function X(){ this.name = "x"; this.age = 11; this.say = function(){ console.log(this.name); } } function Y(){ this.name = "y"; this.color = "black"; } /**調用建構函式X返回一個執行個體x*/ var x = new X(); x.say(); //x console.log(x); //X {name: "x", age: 11, say: function()} /**用函數對象X中的屬性擴充項物件y*/ var y = new Y(); console.log(y); //Y {name: "y", color: "black"} X.apply(y); console.log(y); //Y {name: "x", color: "black", age: 11, say: function()} /**函數X在對象環境y中執行把name賦值為X中的值x*/ y.say(); //x y.name = "y"; y.say(); //y
4.原因是環境對象作為this執行了函數中的代碼
var name = "global"; var obj = { name: "obj", callName: function(){this.foo = function(){ console.log("欺騙了IDE"); }; console.log(this.name); } }; obj.callName(); //obj /**當不傳參數給apply時,預設全域環境作為第一個參數;同時全域也會獲得原始環境中的屬性*/ obj.callName.apply(); /**在原來的obj環境中運行函數,搜尋到最近的值還是obj的屬性name的值obj*/ obj.callName(); //obj /** * 當沒有執行上面的apply時,是會報錯的;當然也不建議這樣做 * Uncaught ReferenceError: foo is not defined * 在執行apply時,運行了this.foo=...,這裡的this在運行時指的是全域環境 * 所以在下面執行foo時,會列印出 */ foo();//欺騙了IDE
5.函數運算式模仿塊級範圍避免全域變數衝突
/** * 在通過圓括弧把函式宣告轉化為函數運算式並立刻執行它 * 這個函數內部的環境就是這個函數的環境,從而避免了全域變數衝突 */(function(){var person = { name: "Ameki", age: 18, sayHi: function(){ alert("Hello, " + this.name); } };for(var prop in person){ console.log(prop + ", " + person[prop]); } })(); /* name, Ameki age, 18 sayHi, function (){ alert("Hello, " + this.name); } */
如果你覺得本文對你有協助,請點擊右下方的推薦按鈕,這樣就可以讓更多的小夥伴看到它了。
本文地址:http://www.cnblogs.com/kodoyang/p/Javascript_FunctionApply_ExtendEnvironmentObject.html
雨木陽子
2015年9月22日
Javascript使用函數apply擴充環境對象