// 这个函数是制作蛋糕的机器functionMakeCake(buyer){this.buyer=buyer}// 我们选择一个9寸圆形的草莓蛋糕MakeCake.prototype={size:"9寸",shape:"圆形",taste:"草莓味 "}varstrawberryCake=newMakeCake("Jimmy")// 给jimmy做的草莓蛋糕出炉啦varstrawberryCake2=newMakeCake("Bob")// 再给Bob做一个// 我们选择一个12寸方形巧克力双层蛋糕模型MakeCake.prototype={size:"12寸",shape:"方形",taste:"巧克力",type:"双层的"}varchocolateCake=newMakeCake("Jimmy")// 给Jimmy做一个巧克力蛋糕 :)
那这个蛋糕制造机是怎么被生产出来的呢?制蛋糕的机器也是仿照一个模子通过一台机器制造机做出来的javascript内部有一个机器制造器叫做Function函数。而你可以把function CustomFunction(){...} 视为new Function(args, functionBody) 的语法糖。当你需要一台机器,你就可以使用new Function({...}),这个机器制造器Function就会按照一个默认的模子生产出一台机器。
要说明的是, 语法糖的说法并不是完全准确的,函数声明形式和new Function()不等价,new Function() 效率会低一些。
附一张原型链的图: 对象的__proto__属性指向它的原型
functionCat(name){this.name=name}varjetty=newCat()
其实简单来说,原型就是一个对象对另一个对象的引用。
然后其是怎么联系起来的呢,是通过prototype。对就是这个,给你一个例子
var obj = {a: 2
}
var myObj = Object.create(obj)
console.log(myObj.a) // 2
console.log(myObj === obj) // false
console.log(Object.getPrototypeOf(myObj) === obj) // true
Object.getPrototypeOf(myObj).a = 4
console.log(obj.a) // 4
通过上面的例子,你可以看到,myObj的原型就是obj!然后obj的原型是哪个呢,是Object.prototype。实际上通过上面,你就能知道,原型原理上是对于另一个对象的引用,通过引用吧几个对象给串联起来调用。
那么你的第二个问题马上又来了,可能也是你关心的问题,类和原型的关系是啥呢?
实际上,类在实例化的时候,也就是通过new来创建一个对象的时候,是分为以下几步的:
创建一个全新的对象
这个新对象会被执行prototype连接
新对象绑定到函数调用的this
如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象
这个就是new实例化的时候,所做的一些步骤,那么你其中有几个需要注意的点:
如果有return并且返回的是一个对象的话,则直接返回return后的那个对象。
反之,则新建一个对象。
并且吧函数的prototype引用到新建对象的prototype中。
这个怎么理解呢?再给你一个例子,可能例子更直观一些:
var protoObj = {b: 10
}
function Foo() {}
Foo.prototype = protoObj
var a = new Foo()
console.log(Object.getPrototypeOf(a) === Foo.prototype) // true
console.log(Object.getPrototypeOf(a) === protoObj) // true
console.log(a.b) // 10
通过这个例子,你可以看出来,实际上类实例化的过程,其中有一项,就是把其构造好的对象的prototype和类的prototype做关联。因为做好了引用关联,所以构造好的对象可以使用原类里面的原型方法。
这个也讲完了,那么你可能会对class比较感兴趣,想知道class是怎么做的,实际上,class更多,我理解上就是上面类似于Foo()类的一种语法糖,当然也不仅仅是语法糖,但是大体原理是没啥区别的,所以,上面所说的,对于class也同样适用
好啦,如果你对原型和类实例化有更多想了解的,可以给你两篇文章,参考一下:
Javascript基础之-原型(prototype)
Javascript基础之-this