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日
时间: 2024-11-09 23:59:14