《JS高级程序设计》第6章读书笔记:创建对象(三)再探原型
2017-08-24 23:56
417 查看
《JS高级程序设计》第6章的读书笔记
- 创建对象(一)工场模式和构造函数模式
- 创建对象(二)原型模式和组合模式
- 创建对象(三)再探原型
- 对象继承(一)原型链
- 对象继承 (二)借用构造函数和组合继承
- 对象继承(三)原型式继承和寄生式继承
- 对象继承(四)寄生组合式继承
这一节,我们讨论原型的一些细节。
从上述代码看出,可以无论是通过实例,还是原型访问属性
根据Object.hasOwnProperty()接口和in 操作符可以间接判断一个属性是否存在于原型。
for-in 循环
for-in循环时,返回的是能够通过对象访问的,可枚举的属性,不仅是实例属性,还是原型属性(包括屏蔽了原型中不可枚举的的实例,但是I8及其IE8-是例外,而这是违反规范的。)
Object.keys()
Object.keys()获取对象上所有可枚举的实例属性或者原型属性
Object.getOwnPropertyName()
这个方法可以获取原型对象的所有属性,且无论是否可以枚举。传入参数为原型对象
看下面这段代码。
下图清晰地描述上面代码重写原型后的结果:实例对象的[[prototype]]属性还是指向旧原型对象,不是新原型对象;新构造函数的prototype属性不再指向旧原型对象。
所以friend实例不能访问到新原型对象的方法。
像自定义类型一样,原生类型的属性也可以被修改和增加。
例子可以看:这篇博文
- 创建对象(一)工场模式和构造函数模式
- 创建对象(二)原型模式和组合模式
- 创建对象(三)再探原型
- 对象继承(一)原型链
- 对象继承 (二)借用构造函数和组合继承
- 对象继承(三)原型式继承和寄生式继承
- 对象继承(四)寄生组合式继承
1 前言
其实,在 上一篇博客:《JS高级程序设计》第6章读书笔记:创建对象(二)原型模式和组合模式,我们讨论了原型了模式,但是关于原型,我们还没讲完。这一节,我们讨论原型的一些细节。
2 原型与in操作符
在单独使用in操作符时,如果能够通过对象访问给定属性,无论是是通过原型还是实例,则会返回true
function Person() {} Person.prototype.name = 'Nicholas'; Person.prototype.age = '29'; let p1 = new Person(); console.log('name' in p1); //true p1.name = 'hhhha'; console.log('name' in p1); //true delete p1.name1
从上述代码看出,可以无论是通过实例,还是原型访问属性
name, 调用 name in p1 都返回true。
根据Object.hasOwnProperty()接口和in 操作符可以间接判断一个属性是否存在于原型。
//判断一个属性是否是原型属性 function hasPrototypeProperty(object, name) { return !object.hasOwnProperty(name) && (name in object); } function Person() {} Person.prototype.name = 'achao'; Person.prototype.getName = function() { return this.name; } p1 = new Person(); console.log(hasPrototypeProperty(p1, 'name'));//true
for-in 循环
for-in循环时,返回的是能够通过对象访问的,可枚举的属性,不仅是实例属性,还是原型属性(包括屏蔽了原型中不可枚举的的实例,但是I8及其IE8-是例外,而这是违反规范的。)
//for-in 循环屏蔽原型属性的实例属性 var o = { toString: function() { return 'my object'; } } for (var prop in o) { if (prop == 'toString') { console.log("found tostring"); } }
Object.keys()
Object.keys()获取对象上所有可枚举的实例属性或者原型属性
function Person() {} Person.prototype.name = 'achao'; Person.prototype.getName = function() { return this.name; } p2 = new Person(); p2.name = 'zy'; //Object.keys()获取实例对象上所有可枚举的实例属性或者原型的所有可枚举的原型属性,分别传入原型对象和实例对象 var keys = Object.keys(Person.prototype); console.log(keys); // ['name','getName'] var p2keys = Object.keys(p2); console.log(p2keys);//['name']
Object.getOwnPropertyName()
这个方法可以获取原型对象的所有属性,且无论是否可以枚举。传入参数为原型对象
var allkeys = Object.getOwnPropertyNames(Person.prototype); console.log(allkeys); //['constructor','name','getName']
3 原型的动态性
重写原型会不能建立实例对象和新原型对象之间的联系,而且切断了构造函数与旧原型对象之间的联系。看下面这段代码。
function Person() {} var friend = new Person(); Person.prototype = { constructor: Person, name: 'Nicholas', age: 29, job: "Software Engineer", sayName: function() { console.log(this.name); } } friend.sayName(); //friend.sayName is not a function
下图清晰地描述上面代码重写原型后的结果:实例对象的[[prototype]]属性还是指向旧原型对象,不是新原型对象;新构造函数的prototype属性不再指向旧原型对象。
所以friend实例不能访问到新原型对象的方法。
4 原生对象的原型
所有原生引用类型都是通过原型模式创建的。所有原生类型(Oject,Array,String等等)都原型对象上定义了方法。如Array.prototype.splice()像自定义类型一样,原生类型的属性也可以被修改和增加。
例子可以看:这篇博文
相关文章推荐
- 《JS高级程序设计》第6章读书笔记:创建对象(二)原型模式和组合模式
- [置顶] 《JS高级程序设计》第6章读书笔记:创建对象(一)之工场模式和构造函数模式
- 《JS高级程序设计》第6章读书笔记:继承对象(四)寄生组合式继承
- 《JS高级程序设计》第6章读书笔记:继承对象(二)借用构造函数和组合继承
- 《JS高级程序设计》第6章读书笔记:对象继承(一)原型链
- 《JS高级程序设计》第6章读书笔记:对象继承(三)原型式继承和寄生式继承
- effective java 第2章-创建和销毁对象 读书笔记
- JavaScript构造函数及原型对象 使用Object或对象字面量创建对象 工厂模式创建对象 构造函数模式创建对象 原型模式创建对象 构造与原型混合模式创建对象
- JavaScript对象的创建之动态原型方式
- 在立即执行函数内组合使用构造函数模式和原型模式创建对象,实现模块化开发(以daterangepicker.js为例)
- 在JS中组合使用构造函数模式和原型模式创建对象
- JavaScript中创建对象的几种模式(原型)--源自技术
- javascript使用原型(prototype)方法创建对象
- javascript创建对象——组合使用构造函数和原型模式
- JavaScript构造函数及原型对象 使用Object或对象字面量创建对象 工厂模式创建对象 构造函数模式创建对象 原型模式创建对象 构造与原型混合模式创建对象
- 读书笔记--JavaScript设计模式:Constructor模式(创建对象的方法)
- Objective-C设计模式——原型Prototype(对象创建)
- 【笔记】 《js权威指南》- 第6章 对象 - 6.1 创建对象
- js:对象的创建(基于组合和动态原型)
- 设计模式之Prototype(原型模式)对象创建型