彻底搞清javascript中this, constructor, prototype

说起这三个属性,肯定有一些同学和我一样,初学js时非常困惑,头大,一脸的迷茫。今天就来给大家彻底解决这些担心受怕的问题。

先看this

this定义:

this就是函数赖以执行的对象。

分析这句话:

1. this是对象。

2. this依赖函数执行的上下文环境。

3. this存在函数中。

直接看例子:

alert(this); //在全局环境调用this, this指向window,  输出[Object window]

function Person(){

     alert(this);

}

方式一:

Person(); // 全局环境用Person函数, this指向window,  输出[Object window]

方式二:

var obj = new Person(); //把Person当做构造函数, 实例化一个对象

//此时this指向了obj, 不再指向window,  输出[Object object]

function Person(){

     alert(this.name); //此时无法判断this的身份

}

Person(); //this在全局环境中被调用, this.name == window.name, 输出了窗口的名字

var obj = new Person(); //this在obj环境下被调用, this.name == obj.name, 由于name没被赋值, 所以输出undefined

由此可以看出, 我们在阅读代码或者写代码时,看到某个函数中定义的this时, 还无法去判断那个this身份,必须找到它依赖执行的环境(对象)。

再回头看看this的定义,大家就清楚自然了。

再看constructor和prototype

constructor和prototype的关系非常密切。

constructor是一个对象的属性,这个属性存在在此对象的prototype中, 指向此对象的构造函数。

分析这句话:

1.constructor是一个对象属性。

2.constructor在prototype中

3.constructor指向构造函数

例子1:

function Person(name, age){

      this.name = name;

      this.age = age;

}

Person.prototype.getName = function(){

     alert(this.name);

}

Person.prototype.getAge = function(){

     alert(this.age);

}

var obj = new Person();

alert(obj.constructor == Person);// true

此种方式定义的prototype, constructor是隐藏的, 默认指向Person

例子2:

function Person(name, age){

     this.name = name;

     this.age = age;

}

Person.prototype = {

     getName: function(){

         alert(this.name);

 },

getAge: function(){

         alert(this.age);

   }

}

var obj = new Person();

alert(obj.constructor == Person);// false

为什么是false? 这种定义prototype, 是把prototype重写了, 覆盖了默认的constructor。

换句话说, 其实这种方式就是给属性重新赋值了, 所以导致默认的constructor被覆盖。

此时的obj.constructor将指向的是Object。

改写一下上面的:

Person.prototype = {

      constructor: Person, //强制指向Person

       getName: function(){

            alert(this.name);

      },

    getAge: function(){

        alert(this.age);

    }

}

此时constructor就指向Person了。

prototype是一个函数属性, 此属性同时也是一个对象, 保存着对象实例所共有的属性和方法。

分析这句话:

1.prototype是函数属性, 只要是函数, 就有prototype属性. 而不管是构造函数还是普通函数.

2.prototype同时也是对象.

2.prototype放的是公共的东西, 包括属性和方法.

例子1.

function Person(name, age){

      this.name = name;

      this.age = age;

}

//是函数就有prototype属性, 这个属性也是一个对象

Person.prototype = {

     getName: function(){ //所有对象实例都共享

     return this.name;

  },

  getAge: function(){//所有对象实例都共享

      return this.age;

  }

}

var obj = new Person('tom', 23);

obj.getName(); //'tom'

var obj2 = new Person('jack', 23);

obj2.getName(); //'jack'

obj.getName == obj2.getName; //true, 所有实例共享

Person.prototype.getName(); //当做普通函数属性, 根据this定义, 此时this指向的是Person.prototype, 所以返回undefined

以上就是this, constructor, prototype的定义和他们之间的关系. 可能还有些粗糙, 欢迎大家补充.

综合例子:

var Tinker = function(){

       this.elements = [];

};

Tinker.fn = Tinker.prototype = {

       constructor: Tinker,

       extend: function(obj){

             var p;

           for(p in obj){

              this.constructor.prototype[p] = obj[p];//此处若看明白了, 那么前面的就理解了

       }

     }

}

Tinker.fn.extend({

get: function(){

     var length = arguments.length,

            i = 0;

       for(; i < length; i++){

          this.elements.push(document.getElementById(arguments[i])); //此处若看明白了, 那么前面的就理解了

     }

      return this;//此处若看明白了, 那么前面的就理解了

},

each: function(fn){

      var i = 0,

         length = this.elements.length;

       for(; i < length; i++){

         fn.call(this.elements[i], i, this.elements[i]);

      }

      return this;//此处若看明白了, 那么前面的就理解了

   }

});

这个例子其实很简单, 就是向一个对象原型添加方法.一个方法是get, 用于查找页面id. 一个是each, 用于对找到的id元素执行一个方法

//假设有id = 'data', id = 'message'

var obj = new Tinker();

obj.get('data', 'message').each(function(i, item){

     this.style.cssText = 'height:20px; background:#ff0000';

})

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容