博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Object-Oriented(二)原型对象
阅读量:5331 次
发布时间:2019-06-15

本文共 3241 字,大约阅读时间需要 10 分钟。

自用备忘笔记

 

1. 理解原型对象

只要创建函数,函数上就会创建一个 prototype 属性指向函数的原型对象。

function Person() {}Person.prototype  //指向该函数的原型对象

所有原型对象会自动获得一个 constructor 属性指向 prototype 属性所在的函数。

Person.prototype.constructor === Person;  //true

每个通过构造函数生成的实例对象,都包含一个 [[Prototype]] 属性指向其构造函数的原型对象,在 Firefox、Safari 和 Chrome 中可以通过 __proto__ 来访问。

var Daryl = new Person();Daryl.__proto__ === Person.prototype;  //true

虽然无法通过标准的方法访问 [[Prototype]] 方法,但可以通过 isPrototypeOf() 方法来确实关系。

Person.prototype.isPrototypeOf(Daryl);  //true

ES5新增了一个方法:Object.getPrototypeOf(),该方法可以返回 [[Prototype]] 的值。

Object.getPrototypeOf(Daryl) === Person.prototype;  //true

虽然通过实例对象可以访问原型中的属性,但无法通过实例对象重写原型中的属性。

function Person() {}Person.prototype.name = 'Daryl';var person1 = new Person(),    person2 = new Person();person1.name = 'Nicholas';person1.name;  //Nicholasperson2.name;  //Daryl

对对象属性的访问,是先检索实例上有无该属性,再检索原型对象上有无该属性。若删除实例上的属性,则会恢复对原型对象属性的访问。

person1.name = 'Nicholas';delete person1.name;person1.name;  //Daryl

通过 hasOwnProperty 方法可以检测某个属性究竟来自实例还是原型。

person1.name = 'Nicholas';person1.hasOwnProperty('name');  //trueperson2.hasOwnProperty('name');  //false

 

2. 原型与 in 操作符

in 操作符用来检测某个对象中是否有某个属性,可以单独使用,也可以搭配 for 使用。

person1.name = 'Nicholas';'name' in person1;  //true'name' in person2;  //true 

使用 for-in 遍历对象的属性时会将原型上的属性一起遍历,如果需要滤掉这部分,可以搭配 hasOwnProperty 方法一起使用。

function Person() {}Person.prototype.name = 'Nicholas';var person = new Person();person.age = 29;person.gender = 'male';for (var o in person) {    if (person.hasOwnProperty(o)) {        console.log(o);  //age, gender    }}

ES5新增了 Object.keys 方法,用来返回一个所有可枚举的实例属性的集合。

Object.keys(person);  //['age', 'gender']

如果想要得到所有的属性,无论是否可枚举,可以使用 Object.getOwnPropertyNames

Object.getOwnPropertyNames(Person.prototype);  //['constructor', 'name'] 

以上两种方法都可以用来代替 for-in 循环。

 

3. 更简单的原型语法

为了避免重复书写,可以通过对象字面量的方式重写原型对象。 

function Person() {}Person.prototype = {    name: 'Nicholas',    age: 29,    sayName: function() {        alert(this.name);    }};

这种方式会导致原型对象上的 constructor 属性丢失,可以手动指定 constructor 属性。

function Person() {}Person.prototype = {    constructor: Person,    name: 'Nicholas',    age: 29,    sayName: function() {        alert(this.name);    }};

但 constructor 本身是不可枚举的,可以通过 ES5 新增的 Object.defineProperty() 方法设置。

Object.defineProperty(Person.prototype, 'constructor', {    enumerable: false,    value: Person});

 

4. 原型的动态性

由于在原型中查找值的过程是一次搜索,因此在任何时候对原型对象的修改都会立即反映在实例上。

var Daryl = new Person();Person.prototype.sayHi = function() {    alert('Hi');};Daryl.sayHi();  //Hi

但是重写原型对象会导致构造函数与原型之间的联系被切断。

var Daryl = new Person();Person.prototype = {    sayHi: function() {        alert('Hi');    }};Daryl.sayHi();  //出错

 

5. 原生对象的原型

原型模式不仅应用在自定义类型方面,就连所有原生的引用类型,都是采用这种模式创建的。它们都在其构造函数的原型上定义了方法。

Array.prototype.sort;  //functionString.prototype.substring;  //function

还可以在原生对象上定义新方法,如下,定义一个反转字符串的方法。

String.prototype.reverseString = function() {    return this.split('').reverse().join('');};'Hello World!'.reverseString();  //!dlroW olleH

 

6. 原型的问题

由于原型上所有属性均是共享的,若某个实例对原型中的引用类型属性进行修改,则这一个修改会反映在所有实例上。

function Person() {}Person.prototype.friends = ['Shelby', 'Court'];var person1 = new Person(),    person2 = new Person();person1.friends.push('Van');person2.friends;  //['Shelby', 'Court', 'Van'];

 

转载于:https://www.cnblogs.com/ghost-xyx/p/7910685.html

你可能感兴趣的文章
微信小程序开发7-JavaScript脚本
查看>>
leetcode-78-子集
查看>>
LINUX进程小结
查看>>
公告会看门道:四个不同的厨师和史蒂夫·乔布斯
查看>>
HDU 1983 BFS&&DFS
查看>>
c++开源项目汇总
查看>>
python yield返回多个值
查看>>
每日站立会议及今日份任务
查看>>
R12 付款过程请求-功能和技术信息 (文档 ID 1537521.1)
查看>>
洛谷 4364 [九省联考2018]IIIDX
查看>>
洛谷 3870 [TJOI2009]开关
查看>>
【牛客-16643】统计数字(简单排序)
查看>>
www.aaa.com/index.html跳转www.aaa.com设置
查看>>
ssdb binlog机制 存疑
查看>>
Vue 2.0 组件库总结
查看>>
HDU5033 Building(单调栈)
查看>>
Kafka 安装配置 及 简单实验记录
查看>>
想成为程序猿?28个程序员专供在线学习网站(转)
查看>>
font-style: oblique文字斜体,display:inline-block显示间隙
查看>>
css设置滚动条并显示或隐藏
查看>>