原型是function对象的的属性,原型也是对象
构造函数构造出来的实例能够继承原型上的属性和方法
如下例子
// Person.prototype -- 原型 Person.prototype = {} Person.prototype.name = 'abc' function Person() { this.age = 24 } var person = new Person() console.log(person.name) //abc var person1 = new Person() console.log(person1.name) //abc person.name = 'lyj' //给自身新增一个name属性,不能通过子代修改原型上面的name属性, 也不能删除和新增 console.log(person.name) //lyj console.log(person1.name) //abc console.log(Person.prototype.name) //abc
再看一下例子
function Car() { } var car = new Car() //查看实例对象的构造函数 console.log(car.constructor) // function Car() {} //原因是原型上系统会默认增加constructor属性指向构造函数 // Car.prototype = { // constructor: Car // } console.log(Car.prototype.constructor) //这个constructor可以被修改 function Person() { } Car.prototype.constructor = Person var car1 = new Car() console.log(car1.constructor)
再看一下例子
Person.prototype.name = 'abc' function Person() { // var this = { // __proto__: Person.prototype // } // 构造函数构造时会隐式的在this上加上 __proto__ 属性,指向 Person.prototype 即原型 } var person = new Person() console.log(person.__proto__ === Person.prototype) //true // 实例的 __proto__ 能够被修改 console.log(person.name) var obj = { name: 'lyj' } person.__proto__ = obj //person的原型指向了obj console.log(person.name)
再看以下例子
Person.prototype.name = 'sunny' function Person() { } var person = new Person() Person.prototype.name = 'chery' console.log(person.name) // chery
--------------------------------------------------------
Person.prototype.name = 'sunny' function Person() { } var person = new Person() Person.prototype = { name: 'chery' } console.log(person.name) // sunny
---------------------------------------------------------
//类似下面形式 var obj = {name: 'sunny'} var obj2 = obj obj = {name: 'chery'} console.log(obj2.name)
Person.prototype.name = 'sunny' __proto__ = Person.prototype Person.prototype = {name: 'chery'} console.log(__proto__.name) 'sunny'
--------------------------------------------------------
Person.prototype.name = 'sunny' function Person() { } Person.prototype = { name: 'chery' } var person = new Person() console.log(person.name) // chery
再看以下例子
Person.prototype.obj = { name: 'abc' } function Person() { } console.log(Person.prototype.__proto__ === Object.prototype) //true //函数原型的最终原型就是Object的原型Object.prototype, 也是所有对象的最终原型 var person = new Person() //修改原型的属性 console.log(person.obj.name) //abc person.obj.name = 'lyj' //不会在实例对象上新增obj对象及属性,而是在原型上修改,但特仅限于引用类型,基本类型不行 console.log(person.obj.name) //lyj
再看以下例子
Person.prototype = { name: 'abc', sayName: function() { console.log(this.name) } } function Person() { this.name = 'lyj' } var person = new Person() person.sayName() //lyj Person.prototype.sayName() //abc //谁调用,this指向谁
再看以下例子
var obj = Object.create(原型) 指定对象的原型 var obj = {name: 'abc'} var obj1 = Object.create(obj) console.log(obj1.name) //绝大多数对象最终会继承Object.prototype //个别不会 比如通过 Object.create创造出来的原型且是null var obj = Object.create(null) console.log(obj) //没有__proto__ ,且也不能认为的添加 __proto__ //Object.create()参数里面只能放 object 和 null //undefined和null没有toString()方法 //string. number, boolean有toString()方法是因为会转化为包装类,这些包装类上有toString()方法 //重新,子代上实现和原型上一样的功能方法 var obj = 123 document.write(obj) //123 var obj = {} document.write(obj) //[object Object] var obj = Object.create(null) document.write(obj) //报错 因为输出到页面中会默认调用toString方法,而用原型null创造的obj是没有toString()方法 obj.toString = function() { return 'hello' } document.write(obj) //hello 默认会调用obj上的toString()方法
end !!!