《JavaScript 语言精粹》 学习笔记 —— 第五章 继承

来源:互联网 发布:xampp下的mysql配置 编辑:程序博客网 时间:2024/04/29 06:17


第五章 继承

5.1、继承的两个作用:1、代码重用;2、类型系统规范。
5.2、JavaScript是一门弱类型的语言。不需要类型转换。对象的起源是无关紧要的。
5.3、JavaScript是一门基于原型的语言,而不是基于类的语言。
5.4、JavaScript的prototype。
当一个函数对象被创建时,Function 构造器产生的函数对象会运行类似这样的一些代码:
this.prototype = { constructor : this };
新函数对象被赋予一个 prototype 属性,其值是包含一个 constructor 属性且属性值为该新函数对象。该 prototype 对象是存放集成特征的地方。因为JavaScript语言没有提供一种方法去确定哪个函数是打算用来作构造器的,所以每个函数都会得到一个prototype对象。
5.5、当采用构造器调用模式,即使用 new 前缀 去调用一个函数时,将修改函数执行方式。
5.6、定义一个构造器,扩充它的原型:
var Mammal = function (name) {this.name = name;};Mammal.prototype.get_name = function () {return this.name;};Mamal.prototype.says = function () {return this.saying || '';};再构造一个实例:var myMammal = new Mammal('Herb the Mamal');var name = myMammal.get_name(); // 'Herb the Mammal';document.writeln(name);构造一个伪类来继承Mammal,这是通过定义它的constructor函数并替换它的prototype为一个Manmal的实例来实现的:var Cat = function (name) {this.name = name;this.saying = 'meow';};// 替换 Cat.prototype 为一个新的 Mammal 实例Cat.prototype = new Mammal();// 扩充新原型对象,增加 purr 和 get_name 方法Cat.prototype.purr = function (n) {var i, s = '';for (i = 0; i < n; i += 1) {if (s) {s +- '-';}s += 'r';}return s;};Cat.prototype.get_name= function () {return this.says() + ' ' + this.name + ' ' + this.says();};var myCat = new Cat('Henrietta');var says = myCat.says(); // 'meow'var purr = myCat.purr(5); // 'r-r-r-r-r'var name = myCat.get_name(); // 'meow Henrietta meow'
使用构造器函数存在一个严重的危害。如果在调用构造器函数时忘记了在前面加上 new 前缀,那么 this 将不会被绑定到一个新的对象上,而被绑定到全局对象上,所以不但没有扩充新对象,反而破坏了全局变量。更恶心的是,发生了这样情况时,既没有编译时警告,也没有运行时警告。
  这是一个严重的语言设计错误。为了降低这个问题带来的风险,所有的构造器函数都约定命名成首字母大写的形式,并且不以首字母大写的形式拼写任何其他的东西。这样可以通过目视检查去发现是否缺少了 new 前缀。一个更好的备选方案就是根本不使用 new。
5.7、在一个纯粹的原型模式中,会摒弃类而专注于对象。
5.8、使用函数模块模式的应用来解决继承中父类属性私有化的问题。

总结:
1、prototype 对象中有一个 constructor 属性,它指向当前对象的一个引用。
2、一个不成文的约定,如果替换了prototype对象:
o.prototype = {};
那么,下一步需要为新的 prototype 对象加上 constructor 属性,并将这个属性指回原来的构造函数。
o.prototype.constructor = o;
原因是前一步已经删除了这个prototype对象原来的值,所以新的prototype对象没有constructor属性,所以我们必须手动加上去,否则后面的“继承链”会出问题。

3、这一章个人感觉JavaScript中的继承还是可以理解的,但读起来特别费劲,收藏3篇不错的进阶文章《Javascript 面向对象编程(一):封装》、《Javascript面向对象编程(二):构造函数的继承》和《Javascript面向对象编程(三):非构造函数的继承》。


转载请注明出处:http://blog.csdn.net/xxd851116/article/details/7671802