原型
查找原型
1 2
| obj.__proto__ (隐式原型) obj.getPrototypeOf(obj)
|
对象的原型
–proto–
当通过[[get]]方式获取一个属性对应的value时
- 它会优先在自己的对象中查找,如果找到直接返回
- 如果没有找到,那么会在原型对象中查找
函数原型
将函数看成是一个普通对象时,它是具备__proto__
将函数看成是一个函数时,它是具备prototype
new操作符
- 在内存中创建一个新的对象(空对象);
- 在这个对象内部的__proto_属性会被赋值为该构造函数的prototype属性
**意义:**当多个对象拥有共同的值时,我们可以将它放到构造函数对象的显式原型;由构造函数创建出来的所有对象,都会共享这些属性
Constructor
原型对象上是有一个属性:constructor
默认情况下原型上都会添加一个属性constructor,这个constructor指向当前的函数对象
重写函数原型对象
当函数原型需要添加太多东西时,可以重写原型对象
1 2 3 4 5 6 7 8
| Person.prototype = { message: "hello person", info: {name:"haha", age:30}, running: function() {}, eating: function() {}, constructor:Person }
|
对象原型链
一个对象上获取属性,如果当前对象中没有获取到就回去它的原型上面获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var obj = { name = "why", age:18 }
obj.__proto__ = { }
obj.__proto__.__proto__ = { }
obj.__proto__.__proto__.__proto__ = { address:"xixihah" }
|
实现继承
原型链实现方法继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| function Person(name, age){ this.name = name this.age = age }
Person.prototype.running = function() { console.log("run") } Person.prototype.eating = function() { console.log("eating") }
function Student(name, age,sno,score){ this.name = name this.age = age this.sno = sno this.score = score }
Student.prototype.studying = function() { console.log("eating") }
var p = new Person("why", 18) Student.prototype = p
|
借用构造函数实现属性继承
1 2 3 4 5 6 7 8 9 10
| function Person(name, age){ this.name = name this.age = age }
function Student(name, age,sno,score){ Person.call(this,name,age) this.sno = sno this.score = score }
|
以上配合使用叫做组合继承
实现了继承但存在很多缺点
- 无论什么情况都会调用两次构造函数
- 所有子类实例事实上有两份父类属性
- 一份在实例自己里面(person本身的),另一份在子类的原型对象中(person.-proto-里面)
寄生组合继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function Person() {} function Student() {}
var obj = {} Object.setPrototypeOf(obj, Person.prototype) Student.prototype = obj
function F() {} F.prototype = Person.prototype Student.prototype = new F()
var obj = Object.create(Person.prototype) Student.prototype = obj
function inherite(Subtype, Supertype){ Subtype.prototype = Object.create(Supertype.prototype) Object.defineProperty(Subtype.prototype, "constructor", { enumerable: false, configurable: true, writable: true, value: Subtype }) }
|
对象的部分方法
**hasOwnProperty:**对象是否有某一个属于自己的属性(而不是原型属性上)
**in/for in:**判断某个属性是否在某个对象或者对象的原型上(变量的不仅仅是自己对象上的内容,也包括原型上的内容)
**instanceof:**用于检测构造函数的prototype(Person,Student类)是否出现在某个实例对象的原型链上
isPrototypeOf用于检测某个对象是否出现在某个实例对象的原型链上
1 2 3 4 5 6 7 8 9 10 11 12 13
| var obj = { name: "why", age:18 }
var info = createObject(obj) info.address = "xx"
clg(info.hasOwnProperty("name")) clg(info.hasOwnProperty("address"))
clg("name" in info) true
|
构造函数的类方法
通过prototype添加方法可以看作实例方法
1 2 3 4 5 6 7 8 9 10
| Person.prototype.running = function() { console.log("run") }
Person.randomPerson = function() { return new Person("abc", 225) }
|