0%

Frontend-Day13——Prototype

原型

查找原型

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
}

以上配合使用叫做组合继承

实现了继承但存在很多缺点

  1. 无论什么情况都会调用两次构造函数
    • 一次创建子类原型时
    • 另一次在子类构造函数内部
  2. 所有子类实例事实上有两份父类属性
    • 一份在实例自己里面(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() {}

// Method1
var obj = {}
Object.setPrototypeOf(obj, Person.prototype)
Student.prototype = obj

//Method2
function F() {}
F.prototype = Person.prototype
Student.prototype = new F()

//Method3
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"))//false因为是继承过来的
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对象本身的方法
Person.randomPerson = function() {
return new Person("abc", 225)
}

-------------本文结束感谢您的阅读-------------