构造函数
看下面的Star构造函数
1 2 3 4 5 6 7 8 9 10 11 12
| function Star(uname, age) { this.uname = uname this.age = age this.sing = function() { console.log("i am singing") } }
let ldh = new Star("ldh", 22) let zxy = new Star("zxy", 23) ldh.sing() zxy.sing()
|
构造函数最大的问题就是:存在浪费内存的问题。
ldh
和zxy
的sing方法都是一样的,但是必须创建两个地址块分别给两个人用

prototype对象
为了解决这个的问题,让所有对象使用同一个函数,节省内存,就需要使用原型
- 猴枣函数通过原型分配的函数是所有对象共享的。
- 每个构造函数都有一个prototype属性,用于指向prototype对象,这个对象的所有属性和方法,都会构造函数所拥有
简单来说,原型对象的作用就是:共享方法。
1 2 3 4 5 6 7 8 9 10 11 12
| function Star(uname, age) { this.uname = uname; this.age = age; }
Star.prototype.sing = function() { console.log("i am singing") }
let ldh = new Star("ldh", 22) let zxy = new Star("zxy", 23) console.log(ldh.sing === zxy.sing)
|
一般情况下,把公共属性定义到构造函数里面,公共方法放到原型对象对象上
对象原型__proto__
所有对象都会有一个__proto__
只想够高函数的prototype原型对象,致所有我们对象可以使用构造函数的prototype对象的属性和方法,就是因为对象有__proto__
属性。
__proto__
属性和构造函数的prototype是等价的。
__proto__
的意义就在于为查找对象的属性和方法提供一条查找路线。
方法的查找规则:先在ldh对象身上是否有sing方法,如果没有,就根据__proto__
属性,去对应的原型对象查找
1 2 3 4 5 6 7 8 9 10 11 12
| function Star(uname, age) { this.uname = uname; this.age = age; }
Star.prototype.sing = function() { console.log("i am singing") }
let ldh = new Star("ldh", 22) let zxy = new Star("zxy", 23) console.log(ldh.__proto__ === Star.prototype)
|
原型对象的construtor属性
一般来说,每个prototype对象都有一个constructor属性,用于记录该对象引用于那个构造函数,将原型对象重新指向原来的构造函数。
简单来说,构造函数和原型对象是互相引用的
- 构造函数通过
prototype
属性引用到原型对象。
- 原型对象通过
coustructor
属性引用到构造函数。
将原型对象从object改成map
因为原型对象本身只会用到点号去获取属性,根据鸭子类型,我们可以将构造函数的prototype属性改成map。但是因为原型对象有一个constructor属性,所以需要另加一个constructor这个key
1 2 3 4 5 6 7 8 9 10
| function Star(uname, age) { this.uname = uname; this.age = age; }
Star.prototype = { constructor : Star, sing : function(){ console.log("i am singing") }, dance: function(){ console.log("i am dancing") } }
|
原型链

原型的this指向
原型的this就是指向实例本身
call函数修改this的指向
1 2 3 4 5 6 7 8 9 10 11
| function fn() { console.log("hello world") console.log(this) }
var hyl = { name: "123" }
fn.call(); fn.call(hyl);
|
子构造函数 继承 父构造函数 的construtor
1 2 3 4 5 6 7 8 9 10 11 12
| function Father(uname, age) { this.uname = uname this.age = age }
function Son(uname, age, sex) { Father.call(this, uname, age) this.sex = sex }
var son = new Son("asd",15,"male")
|
子构造函数 继承 父构造函数 的自定义方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function Father(uname, age) { this.uname = uname this.age = age }
Father.prototype.money = function() { console.log("i am earnMoney") }
function Son(uname, age, sex) { Father.call(this, uname, age) this.sex = sex }
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.protptype.exam = function() { console.log("i am examing") } var son = new Son("asd",15,"male")
|
