最近一两个月开始转向前端,跟着组里的大牛们做着数据分析和展示的项目。前端并不像我去年大三的时候想的那么简单和浅薄,现在流行的富客户端+REST模式让前端开发大有可为。陆陆续续看了好几本关于js的书,对于js有了更深的认识和理解,也解决了自己之前的一些困惑。所以想写一个系列,来讲一讲JS中一些令人困惑的知识点,希望能给学习了JS基础,但是对JS理解不深的同学一点帮助。
这篇就先讲讲JS中函数的调用模式,或者说,JS中this的指向问题。
当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this被绑定到该对象。
function A() { this.x = 1; //定义a.x this.b = function () { //定义a.b this.helper = function () { //定义a.helper console.log(this); //4.console.log(a) } this.helper(); //3.调用a.helper(); 此时的helper,是一个方法,所以helper中的this指向a } this.b(); //2.调用a.b(),此时的b是a的一个属性,所以是一个方法,所以b中的this指向a } var a = new A(); //1.创建a对象
输出: A {x:1}
当一个函数不是一个对象的属性时,就是被当做一个函数来调用的。此时this被绑定到全局对象。
function A() { this.x = 1; this.b = function () { var helper = function () { console.log(this); } helper(); //此时的helper不是任何对象的属性,只是一个函数 } this.b(); } var a = new A();
用new关键字,此时this被绑定到创建出来的新对象上。
function A() { this.x = 1; this.b = function () { this.helper = function () { //定义aa.helper console.log(this); //4.console.log(aa) } this.helper(); //3.调用aa.helper(); 此时的helper,是一个方法,所以helper中的this指向aa } var aa = new this.b(); //2.创建一个新的对象aa,所以b()中的this指向aa } var a = new A(); //1.创建a对象
输出: A.b {} ;
另外,这里举Splunk吉祥物pony的例子来说一说new操作符做的事情:
function Pony(color) { // var this = Object.create(Pony.prototype); // instance members this.color = color; // private members var age = 50; // private methods function secreteMethod() { console.log('Secret!'); } // make private member visible due to closure this.getAge = function() { console.log('My age is : ' + age); }; // return this; } // methods Pony.prototype.tellColor = function() { console.log('I am ' + this.color); }; // static attributes Pony.type = 'horse'; var pony = new Pony('white'); pony.tellColor(); pony.getAge();
var pony = new Pony('white'); // equals var pony = {}; pony.__proto__ = Pony.prototype; Pony.call(pony, 'white');
function People (name) { this.name = name; } People.prototype.greet = function () { console.log('hi,'+this.name); }; var dog = { name: 'hobbo' }; People.prototype.greet.apply(dog);输出: hi,hobbo