发表于: 2018-06-13 21:22:21

1 517


今天完成的事情

  1. 学习组件,为什么要拆组件,开始任务14,拆出属于自己的组件库
  2. 听老大的讲座——敏捷开发
  3. 学习JavaScript

明天计划的事情

  1. 继续学习拆组件的相关知识
  2. 继续学习JavaScript

遇到的问题

暂时没有遇到新问题

收获

今天学习了JavaScript的原型和原型链的部分知识

原型模式

我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而则个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

换句话说,不必再构造函数中定义对象实例的信息,而是可以将这个写信息直接添加到原型对象中。

示例:

理解原型对象

无论什么时候,只要创建了一个函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象,在默认情况下,所有原型对象都会自动获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针

当调用构造函数创建一个新实例后,该实例的内部将包含一个指针,指向构造函数的原型对象。

下图展示了各个对象之间的关系:

原型对象

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先 从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到, 则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这 个属性,则返回该属性的值。也就是说,在我们调用 person1.sayName() 的时候,会先后执行两次搜 索。首先,解析器会问:“实例 person1 有 sayName 属性吗?”答:“没有。”然后,它继续搜索,再 问:“ person1 的原型有 sayName 属性吗?”答:“有。”于是,它就读取那个保存在原型对象中的函 数。当我们调用 person2.sayName() 时,将会重现相同的搜索过程,得到相同的结果。而这正是多个 对象实例共享原型所保存的属性和方法的基本原理。

虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。(只能屏蔽,但不能重写)

换句话说,给实例添加一个属性只会阻止我们访问原型中的那个属性,但不会修改原型中的属性。即使设置这个属性为null,额只会在实例中设置这个属性,而不会恢复其指向原型的链接。

不过,使用delete操作符则可以完全删除实例属性。如下例所示:

原型与in操作符

in操作符有两种使用方式:

  1. 单独使用
  2. 在for-in 循环中使用

在单独使用时,in操作符会在通过对象能够访问给定属性时返回true,无论属性存在于实例中还是原型中。

看下面的例子:

由于in操作时只要通过对象能够访问到属性就返回true,hasOwnProperty()只在属性存在于实例中才返回true,因此只要in操作符返回true而hasOwnProperty()返回false, 就可以确定属性时原型中的属性。

更简单的原型语法

尽管可以随时为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,但如果是重写整个原型对象,那么情况就不一样了。我们知道,调用构造函数时会为实例添加一个指向最初原型的[[Prototype]] 指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。请记住:实例中的指针仅指向原型,而不指向构造函数。看下面的例子。

重写prototype

组合使用构造函数模式和原型模式

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实 例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本, 但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参 数;可谓是集两种模式之长。下面的代码重写了前面的例子。

动态原型模式

寄生构造函数模式

这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象;但从表面上看,这个函数又很像是典型的构造函数。

稳妥构造函数模式

所谓稳妥对象,指的是没有公共属性,而且其方法也不引用 this 的对象。稳妥对象最适合在 一些安全的环境中(这些环境中会禁止使用 this 和 new ),或者在防止数据被其他应用程序(如 Mashup程序)改动时使用。稳妥构造函数遵循与寄生构造函数类似的模式,但有两点不同:一是新创建对象的实例方法不引用 this ;二是不使用 new 操作符调用构造函数。按照稳妥构造函数的要求,可以将前面的 Person 构造函数重写如下。

稳妥构造函数模式提供的这种安全性,使得它非常适合在某些安全执行环境下使用。

继承

原型链

基本思想:

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。假如,我们让原型对象等于另一个类型的实例,显然,此时的原型对象将包含一个指向另一个原型的指针。

实现原型链有一种基本模式,其代码大致如下:

这个例子中的实例以及构造函数和原型之间的关系如图

原型链关系图)

确定原型和实例的关系

可以通过两种方式来确定原型和实例之间的关系

  • instanceof操作符

只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回true

alert(instance instanceof Object); //true

alert(instance instanceof SuperType);//true

alert(instance instanceof SubType);//true

只要是原型链中出现过的原型

  • isPrototypeOf()方法

只要是原型链中出现过的原型,都可以说是该原型链所派生的实例原型,因此isPrototypeOf()方法也会返回true

谨慎地定义方法

子类型有时候需要重写超类型中的某个方法,或者需要添加超类型中不存在的某个方法。但不管怎样,给原型添加方法的代码一定要放在替换原型的语句之后。



返回列表 返回列表
评论

    分享到