对象的原型隐式原型(对象的原型)早期的ecma并没有规定如何查看原型大多数浏览器都为对象提供了一个属性__proto__,让我们看一下原型对象varobj={name:"hahha"}//只能查看原型对象console.log(obj.__proto__);//es5提供方法api后,可以获取对象原型console.log(Object.getPrototypeOf(obj));//一般开发就用__proto__做测试,api太长而且每个对象里面都用[[prototype]]不方便,一般可以通过__proto__或者getPrototypeOf方法得到我们所谓的隐式原型,我们一般不会不会被处理,也不会被看到,也不会直接使用其原型的作用//当我们从对象中获取某个属性时,会触发[[get]]操作//在查找中有两个操作过程中//1.在当前对象中搜索该对象的属性,如果找到,会直接使用//2.如果没有找到,会沿着原型链查找//原型和当前对象没有age属性console.log(obj.age);//undefined//可以加上ageattributetotheprototypeofthecurrentobjectobj.__proto__.age=18console.log(obj.age);//18显示原型(函数Prototype)2:显示原型(函数的对象)`functionfoo(){}`函数也是一个对象,所以它也有一个隐式原型__proto__[[prototype]]但是这个函数会有一个额外的属性叫做Displayprototype:prototypeprototype浏览器没有提供,所以不存在浏览器兼容性问题。此时ecma提供的console.log(foo.prototype);显示原型最重要的作用是第二个当传递new关键字时调用构造函数时1.在内存中新建一个对象(空对象)2.这个对象内部的[[prototype]]属性会被赋值为原型构造函数的属性3.构造函数内部的this会指向创建的新对象4.执行函数内部代码(函数体代码)5.如果构造函数没有返回非空对象,则返回创建了新对象//例如,函数Person(){}varp1=newPerson()varp2=newPerson()//由于指向内存空间的地址相同,所以打印结果为trueconsole.log(p1.__proto__==Person.prototype);//trueconsole.log(p2.__proto__==Person.prototype);//trueconsole.log(Person.prototype);//{}//打印函数原型显示为空对象,其实不是空的,而是因为enmerable里面的值为false,不可枚举//prototype其实包含一个属性叫constructorconsole.log(Person.prototype.constructor);//constructor指向构造函数本身//我们也可以手动将属性Person.prototype添加到原型中。sname='jeonghan'vars1=newPerson()//当前对象s1上没有sname属性,通过原型找到snameconsole.log(s1.sname);//我们可以在函数原型上添加属性这样Person.prototype.sname='jeonghan'//但是当要添加的属性比较多的时候不方便//我们可以直接修改整个原型对象Person.prototype={//这样就直接修改了整个原型Objectname:"why",age:19,height:1.88}//原型中也会有constructor属性。由于constructor属性不可枚举,这里添加Object.defineProperty(Person.prototype,"constructorbydefineproperty",{enumerable:false,configurable:true,writable:true,value:Person})vars2=newPerson()
