构造函数模式
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
this.sayName = function(){
alert(this.name)
}
}
var person1 = new Person('Nich', 20, 'developer')
var person2 = new Person('Gerg', 18, 'designer')
-
new 操作符
- 创建一个新对象
- 将构造函数的作用域赋给新对象(this指向新对象)
- 执行构造函数中的代码(为这个新对象添加属性)
- 返回新对象
构造函数创建的对象有全新的作用域,所以实例的方法和属性都是私有的
person1.sayname === person2.sayName //false
-
instanceof 操作符
检测对象类型person1 instanceof Object //true person1 instanceof Person //true
-
constructor属性
构造函数创建的实例都有一个constructor属性,该属性指向构造函数person1.constructor === Person //true
-
构造函数的问题
构造函数创建的实例,会导致不同的作用域链和标识符解析。换句话说,不同实例上的方法是不相等的。创建多个完成相同任务的方法是不必要的。
解决方法:将函数定义转移到构造函数外部function Person(name, age, job){ this.name = name this.age =age this.job = job this.sayName = sayName } function sayName() { alert(this.name) }
这样就能实现所有实例的共用方法。如果对象需要定义很多方法,就需要定义多个全局变量。也就没有封装性可言了。我们可以使用原型模式来解决这个问题。
原型模型
function Person(){}
Person.prototype.name = 'Nico'
Person.prototype.age = 18
Person.prototype.sayName = function(){
alert(this.name)
}
var person1 = new Person()
var person2 = new Person()
屏幕快照 2018-11-02 05.41.25.png
- Object.getPrototypeOf()
Person.prototype.isPrototypeOf(person1) //true
- 如果像实例添加原型同名属性,将会屏蔽原型属性(原型链),即使设为null。要想重新访问原型属性,可以使用delete操作符
- in操作符
通过对象能够访问给定属性时返回true,无论属性属于实例还是原型。
4.简洁的原型语法
这种写法相当于重写prototype属性,因此constructor属性指向Object,可以手动设置function Person(){} Person.prototype = { name: 'Nico' age: 19 job: 'developer' sayName: function(){ alert(this.name) } }
constructor: Person
- 原型的动态性
在原型中查找值的过程是一次搜索,因此我们对原型对象的任何修改都能从实例上反映出来。
实例与原型之间的连接是一个指针,而非副本。var friend = new Person() Person.prototype.sayHi = function(){ alert('hi') } friend.sayHi() //'hi'(没问题)
如果是重写整个原型对象,就会切断构造函数与最初原型之间的联系。实例中的指针仅指向原型,而不指向构造函数function Person(){} var friend = new Person() Person.prototype = { constructor: Person name: 29 job: 'developer' sayName: function(){ alert('this.name') } } friend.sayName() //error
- 原型对象的问题
原型中的所有属性都是被实例共享的。当我们需要定义私有属性的时候就有些不方便了。
所以,较好的方式是结合构造函数模式和原型模式
组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性
function Person(name, age, job){
this.name = name
this.age = age
this.job = job
this.friends = ['a', 'b']
}
Person.prototype = {
constructor: Person,
sayName: function(){
alert(this.name)
}
}
本篇文章是 JavaScript高级程序设计__面向对象的程序设计 部分的读书笔记。刚接触js的时候读了一遍,在写了js一段时间后再读一遍,收获颇丰。文章写得浅显易懂,思路清晰,强烈建议有需要了解这部分知识的阅读原文。
网友评论