- 在面向对象编程中,类和对象可想象为铸模和铸件地关系,对象总是从类中创建。
- 在原型编程地思想中,类不是必须的,对象也不一定从类中创建。 对象是通过克隆另一个对象得到的 ,如果需要一个和某对象一摸一样的对象,就可以用原型模式
-
Object.create 可以用来克隆对象
var Plane = function(){ this.blood = 100; this.attackLevel = 1; this.defenseLevel = 1; }; var plane = new Plane(); plane.blood = 500; plane.attackLevel = 10; plane.defenseLevel = 7; var clonePlane = Object.create(plane); console.log(clonePlane); // 输出:Object {blood: 500, attackLevel: 10, defenseLevel: 7} 复制代码
在不支持 Object.create 方法的浏览器中,则可以使用以下代码:
Object.create = Object.create || function(obj){var F = function(){}; F.prototype = obj; return new F();} 复制代码
- 克隆是创建对象的手段
原型链
假设有一原型链:Object=>Animal=>Dog
当我们尝试调用 Dog 对象的方法,而它本身却没有这个方法时,那么这个对象会把这个请求委托给它的原型 Animal,并顺着原型链委托下去,直至找到该方法或者到达根对象。
JavaScript 中的原型继承
- 按照 JavaScript 设计者的本意,除了 undefined 之外,一切都应是对象。为了实现这一目标,number、boolean、string 这几种基本类型数据也可以过“包装类”的方式成对象类型数据来处理。
- js 中的根对象是 Object.prototype 空对象。
- js 中的函数既可以当作普通函数使用,也可以作为构造器调用。当使用 new 运算符调用函数时,这个函数就是构造器
- 就 js 的真正实现,并不能说对象有原型,而只能说对象的构造器有原型,对象把请求委托给它的构造器的原型。
- js 给对象提供了一个命为 proto 隐藏对象,proto 指向构造器的原型对象,{Constrctor}.prototype
-
手动给新建对象设置正确得 __ proto __ 指向可使用
obj.__proto__ = Constructor.prototype 复制代码
- js 的对象最初都是由 Object.prototype 对象克隆而来,但是对象构造器的原型可以动态指向其他对象,从而达到继承的效果。
-
实现一个”类“继承另一个类的效果
var A = function(){} A.prototype = {name:'sven'} var B = function(){} B.prototype = new A() var b = new B() console.log(b.name) 复制代码
- 尝试遍历 b 的所有属性,没有找到 name
- 将请求委托给 b 的构造器的原型,它通过 b.__ proto __ 指向 B.prototype,B 的原型是一个由 A 构造器创造出来的对象
- 在 B 的原型中依然没有找到 name 属性,于是将请求委托给 new A() 对象的构造器原型 A.prototype
- 在 A.prototype 中找到 name 属性,并返回他的值
- 继承总是发生在对象与对象之间
- Object.prototye 的原型是 null,当请求委托到此却没与找到相应属性时,返回 undefined
- 设计模式是对语言不足的补充
- 通过设置构造器原型来实现原型继承时,初根对象 Object.prototype 本身外,任何对象都会有一个原型。而通过 Object.create(null) 可以创建出没有原型的对象。(Object.create 创建对象的效率不高)
- Es6 的 class 语法,其背后仍是通过原型机制创建对象。