关于prototype的疑惑

先看看代码

function dd() {
    this.init();
}
dd.prototype = {
    init: function () {
        alert(1);
    }
}
new dd();

求大神分析一下这段代码。

阅读 4.3k
7 个回答
function dd() {
    this.init();
}
dd.prototype = {
    init: function () {
        alert(1);
    }
}
var ddObject=new dd();

当使用new操作符 调用一个函数时,dd函数就是个构造函数;new操作符调用dd构造函数后,首先会创建一个对象,这个对象以dd.prototype为原型,同时赋值个this;在dd函数没有return语句或return语句返回的值为基本类型非对象的情况下,返回给ddObject,如果没有ddObject,那就会被丢弃~~
在dd构造函数的调用过程中,执行了this.init();这个this就是新创建的对象,这个init方法就是dd.prototype中定义的init函数对象-对象在调用属性或方法时会沿着原型链查找,那么执行这个方法就会alert(1)

new关键字使得dd成为构造函数。没有new就是普通函数。构造函数会创造一个空对象,对象的属性由构造函数生成,并且构造出来的对象的原型指向为dd的prototype使得对象可以访问里面的方法,对象的原型可以指向别的地方,随便指。只是构造函数自动让它指向自己的prototype。记住,只有函数有prototype,只有函数是构造函数时才有实际价值。否则它只是一个函数的一般属性而已。

首先明确new是什么操作- http://es5.github.io/#x11.2.2 ,归根结底是内部的[[contruct]]方法 - http://es5.github.io/#x13.2.2 ,注意其中:

Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.

即,new操作到最后时,会调用构造函数,即本例中的dd。这就是会有alert(1)的原因。

而new dd()会产生一个新的对象,其__proto__为dd.prototype,这也就是为什么new dd() 后会访问到init的原因。

理解原型对象,只要创建了一个新函数,就会为该函数创建一个prototype属性,指向函数的原型对象。

举个例子
clipboard.png
把dd看成是Person,new dd()是一个dd的实例,它包含一个内部属性,该属性指向dd.prototype。所以new dd可以通过查找对象属性来调用init
clipboard.png

补充:Person.prototype指向原型对象,Person.prototype.constructor指向Person

  • 每个函数都可以是一个对象,每个函数都可以是一个构造函数,每个函数都有原型。这是javascript的特性。

  • this的指向都是通过执行上下文来决定的。
    一般情况下,这里的this会指向window,而new的存在,让this指向了原型

这里的this并不是单纯的指向原型,他会在构造函数到原型之间有一个查找过程,比如this.name,如果在构造函数能够找到,this就指向构造函数,如果构造函数中找不到,才会指向原型。 - -,总的来说就是比较复杂,我也不知道应该如何准确表述这里面的关系,就暂且这样吧,不会偏差太多。

大概就是这2个点吧,应该没有别的难以理解的地方了。

   摘抄《JavaScript Ninja》
  • 所有的函数在初始化的时候都有一个 prototype 属性,该属性的初始值是一个空的对象。

  • 只有函数在作为构造器的时候,prototype 属性才会发挥更大的作用。

  • JavaScript 原型的主要用途就是使用一种类风格的面向对象和继承技术进行编码。

  • 使用 new 关键字调用一个函数,使得该函数可以作为构造器进行实例化,并产生一个新的空对象实例作为其上下文(在没有显示 return 的情况下)。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题