一、原型对象、实例、原型链
先写这么一段代码:
var M=function(){this.name='123'} //ƒ (){this.name='123'}
var a1=new M() //M {name: "123"}
console.log(a1.name) //123
构造函数:现在M就是构造函数。任何一个函数被new使用后,就是构造函数,没被new使用过就是普通函数。(简单说new后面的函数都是构造函数)
实例对象:现在a1就叫做实例,在js中,只要是被new出来的对象都叫做实例对象,也叫实例。(所以说实例都是对象,但是对象就不一定是实例了)
原型对象:现在M.prototype就是原型对象,任何一个函数都有prototype属性,这个属性是声明函数时js自动加的,prototype初始时时一个空对象。这个对象就叫原型对象
他们之间的关系就如同下图:我们暂时只看绿色框中的内容
从图中可得知4种关系:
1、构造函数(例子中的M)new出来的东西就叫实例
2、构造函数(例子中的M)的prototype属性就叫原型对象
3、原型对象(M.prototype)中的constructor其实就等于构造函数,可以打印一下 M.prototype.constructor===M //true
4、实例(例子中的a1)的__proto__属性其实就是把他构造函数(M)的prototype
可以打印 a1.__proto__===M.prototype //true
这个时候我们就知道原型对象是干嘛的了吧,原型对象就是用来区分它是哪个构造函数引用的,而且如果多个实例中的方法相同,我们就可以把方法写在prototype原型对象中,prototype属性是可以被多个实例共有,想要你就new一下
接下来我们看图的另一半
__proro__是任何对象都有的属性,而在js中,万物皆对象。所以会形成一条__proro__连起来的链条,递归访问__proto__最终到头,并且值是null,这个过程从头到结束就叫原型链
如果没看到上面的意思,我就再翻译成大白话!:
要查一个实例对象中的值时,首先通过本身的__proto__属性找到他的原型对象,然后再通过他的原型对象的__proto__找到他的原型对象,一直找,递归访问__proto__最终到头,并且值是null,这个过程从头到结束就叫原型链。找到了就返回值,找不到就返回undefind
还有一个比较重要的,不止构造函数有__proto属性,普通函数也有,因为普通函数是Function的实例。
ar M3=function(){this.n=1}
M3.__proto__.constructor === Function //true
二、先说创建对象的3种方法:
//自变量创建,通过原型链指向Object
var o1 = {name:123}
var o2 = new Object({name:123})
//构造函数创建
var M = function(name){this.name=name}
var o2 = new M(123)
//注意,如果 M 不需要入参可以写成
var M = function(){this.name=123}
var o2 = new M
//object.create()给参数中这个对象,作为一个新对象的原型对象,赋值给o4
var p = {name:123}
var o4 = object.create(p)
看懂了就点个赞给我评论,让我开心开心^_^