5. 原型链
prototype 原型
'每一个构造函数都有一个属性叫做prototype,指向一个对象,'
当这个构造函数被new 的时候,它的每一个实例 (即将生成的对象)的__proto__属性,也指向这个对象
function User() { console.log(this); this.name = 'whh'; //即将生成的对象 this.age = 18; } var whh =new User(); console.log(whh); //whh这个对象 User {} age: 18 name: "whh" __proto__: Object constructor: ƒ User() arguments: null caller: null length: 0 name: "User" prototype: {constructor: ƒ}, constructor: ƒ User() __proto__: Object __proto__: ƒ () apply: ƒ apply() arguments: (...) bind: ƒ bind() call: ƒ call() caller: (...) constructor: ƒ Function() length: 0 name: "" toString: ƒ toString() Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]() get arguments: ƒ () set arguments: ƒ () get caller: ƒ () set caller: ƒ () __proto__: Object [[FunctionLocation]]: VM1753:1 [[Scopes]]: Scopes[1] __proto__: Object constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()
每个'函数天生都有prototype属性,指向一个空对象, prototype属性的值是一个对象',也就是说,
我们不需要定义这个prototype属性,任何一个函数只要写出来,它就拥有了prototype属性,
这个属性对它自己而言没有任何意义!它的唯一意义是儿子们 (即将生成的对象)的指明灯!
'构造函数的 prototype属性 指向谁,它new出来的儿子的__proto__属性就指向谁''
function People(name,age,sex) { this.name =name; this.age =age; this.sex =sex; } var ming =new People('ming',12,'nan'); console.log(People.prototype===ming.__proto__); //true console.log(whh.__proto__); //whh这个对象 console.log(User.prototype);//或者也是一样的
'称 People.prototype是People构造函数的 “原型”,People.prototype是ming的 “原型对象”'
5.1
__proto__是神器,有原型链查找功能,当'ming身上没有某个属性'的时候,
'系统会沿着ming的属性__proto__去寻找它的原型对象身上有没有这个属性。''
5.2构造函数的prototype指向谁,new 出来的玩意儿的__proto__就指向谁!!!
这个__proto__有'原型链查找功能''
function People(name,age,sex) { this.name =name; this.age =age; this.sex =sex; } People.prototype ={ "teacher":"kao", "sada":12, } var ming =new People('ming',12,'nan'); alert(ming.teacher); //kao alert(ming['teacher']); //kao People.prototype=Math; //Math所属对象None var ming =new People('ming',12,'nan'); alert(ming.random());
ming身上虽然没有random属性,但是小明的__proto__身上有这个属性,
所以ming能够打点调用random属性。
5.3在原型上定义方法
刚才知道如果'把函数写在构造函数里面',就相当于'定义在了对象上',
'此时函数会产生多个不用的副本,影响程序效率,''
此时可以把函数'定义在构造函数的原型'上,
这样所有new出的东西, __proto__就会指向这个对象,从而能够使用这个方法。
function People(name,age,sex) { this.name =name; this.age =age; this.sex =sex; } People.prototype.funName=function () { //important console.log(this); console.log("woshi:"+this.name+"!nianling:"+this.age); }; var ming =new People('ming',12,'nan'); var hong =new People('hong',13,'nv'); console.log(ming.funName()); console.log(ming.funName==hong.funName); //true console.log(ming.funName); People {name: "ming", age: 12, sex: "nan"} age: 12 name: "ming" sex: "nan" __proto__: funName: ƒ () constructor: ƒ People(name,age,sex) __proto__: Object woshi:ming!nianling:12, VM2101:1 ƒ () {console.log(this); console.log("woshi:"+this.name+"!nianling:"+this.age); }
5.4构造函数和实例的关系
构造函数:抽象,定义的是一类对象应该具有什么属性,什么方法, 描述规则,描述蓝图。
实例:具体,根据规则、蓝图创建的一个个具体的实例,它能拥有属性,并且能调用方法。
构造函数中,我们用prototype来定义方法,
'定义的是构造函数的 实例 的方法',不是构造函数的方法。
<input type="button" value="为所有 标签:__,name,proto,People,JavaScript,ming,面向对象,原型,prototype From: https://www.cnblogs.com/dork/p/14019950.html