每个 JavaScript 对象内部都有一个指向其它对象的“指针”或者 “引用“, 并通过这种方式在对象之间建立了一种联系,形成了一种链式结构,我的理解这就是所谓的原型链。
function F() {} // F 是一个函数,函数也是对象,而且每个函数都有一个属性叫:"prototype"var o = new F() // F.prototype 就是 o 的原型对象
console.log(o.name)
// 输出: undefined
F.prototype.name = "foo"
console.log(o.name)
// 输出: foo
// 上面这个例子是想说明:通过 new 在对象 o 与对象 F.prototype 之间建立了联系, 这个建立联系
// 的方式有人叫 "原型继承" 。 当访问的对象属性不存在时,就会沿着原型链去查找。
每个JS对象一定对应一个原型对象
我们所创建的每一个函数,解析器都会下个函数中添加一个属性prototype。每一个函数都有自己唯一的prototype
如果函数作为普通函数被调用,prototype没有任何作用
如果作为构造函数被调用,每一个创建的实例都会有一个__proto__ 隐含属性,这个属性指向这个函数的原型对象
原型对象相当于一个公共区域,所有同意一个类的实例都可以访问这个原型对象,因此可以把这些实例的共有内容放到原型对象中。
语法:MyClass.prototype.(属性、方法) = 具体属性或方法
当进行访问时,会先在对象内部寻找调用的属性或者方法,如果没有,再去原型对象中寻找。
原型对象的优点
因为在创建构造函数时可以将共有属性全部添加到原型对象中,所以不需要对单个对象添加这些属性或方法,可以减少代码量,也不会影响全局作用域,直接就可以使每个对象都拥有这些属性核方法。
in
使用in可以检查对象中是否有该属性,但是原型中有,依然会返回true。
hasOwnProperty
可以检查对象中是否含有该属性,这个方法只有当对象自身含有该属性时才返回true。
原型对象也是一个对象,它也有原型对象。所以当原型对象中没有这些属性或方法时,还会去原型对象的原型对象中寻找,知道找到Object的原型对象中,都没有找到的话就是undefined。
对象的toString方法
在页面中直接打印一个对象:[Object Object],这是toString方法的返回值。
如果希望输出的时其他的内容,可以修改toString方法,也就是在原型对象中添加一个toString方法。
原型对象实现继承
function Father(){}function son(){}// 父类方法Father.prototype.money = function(){}// son继承father的方法,****直接拷贝会出现问题// 直接加这一行赋值代码,会使父类也拥有exam方法Son.prototype = Father.prototype// 可以添加子类独有的方法Son.prototype = function exam(){}避免出现以上的问题,就有了新的解决方案
// Father的实例可以访问原型对象,因此,Son就可以使用Father的原型对象里边的方法Son.prototype = new Father(){}// 如果利用对象的形式修改了原型对象,别忘记使用constructor指回原来的构造函数Son.prototype.constructor = Son