你的位置:首页 > Java教程

[Java教程]Javascript使用函数apply扩展环境对象


 

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日