Javascript继承之最佳实践
尊重原创,转载请注明出处:http://blog.csdn.net/zoutongyuan
什么是继承?
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
在Javascript 中 没有 类的概念, 它是通过构造函数来产生 对象,
构造函数 就是一个普通的函数。通常当函数名 为 大写开头的。我们觉得是构造函数,否则 就是普通的方法。
function A() {
this.name = 'A Class instance';
}
function m1() {
}
既然 Javascript 是 通过构造函数来产生 对象。那我们怎么定义它的 属性、方法呢?
var a1 = new A(); 是新创建一个A类对象,默认情况下。在构造函数中,使用this指向的是 新创建的对象。
而Javascript的对象属性 能够 晚绑定,即
var obj = {};
obj.name = 'obj1';
obj.say = function say() {
console.log(this.name);
}
能够先产生对象,在须要添加属性时。 通过 obj.属性名 或 obj['属性名'] 来加入属性。
所以我们在构造函数中 使用 this.属性名 来 定义产生的 对象 的 属性和方法。
function A() {
this.name = 'A Class instance';
this.say = function() {
console.log('Hi,I am ' + this.name);
}
}
var a1 = new A();
var a2 = new A();
a1.say(); // Hi,I am A Class instance
a2.say(); // Hi,I am A Class instance
我们分析一下上面代码。
创建了 a1,a2 对象,在创建a1。a2 对象的时候 都为其加入一个say()方法,而这2个对象的 say方法 全然一样,
试想想 假设 创建n 个 A类对象,那是不是为这n个对象 加入一个say()方法,那是很浪费内存。
所以在Javascript 中 引用了 prototype 原型的概念:
每个构造函数都有一个prototype 对象。使用构造函数实例化一个对象,訪问这个对象属性时,假设这个对象有该属性。则返回,否则就会在该对象的构造函数的prototype
上找,直到找到就返回,否则返回的是undefined
来验证一下:
在上面代码中,A构造函数中未定义say 方法,
但a1。a2 却 可以 调用say()方法,由于 A函数的prototype 默认指向的是 Object.prototype ;
此时内存中仅仅保存Object.prototype.say,而A产生的对象 是通过原型机制,一层一层往上找,然后调用的。
所以通过 prototype原型机制,我们能够实现代码复用,和继承。
A.prototype.say = function() {
console.log('Hi,I am ' + this.name);
}
function A() {
this.name = 'A Class instance';
}
var a1 = new A();
var a2 = new A();
a1.say(); // Hi,I am A Class instance
a2.say(); // Hi,I am A Class instance
function B() {
this.name = 'B Class instance';
}
B.prototype = new A();
B.prototype.constructor = B;
var b = new B();
b.say();
分析一下上面代码 运行结果:
我们定义了一个B类,并把他的prototype 指向 A的实例对象。
然后产生一个 b 对象,调用b对象 say() ,也输出了内容。
这是为什么呢?
訪问 b 对象属性时, 假设不存在 。就会在其 prototype 訪问,
就是 訪问a 对象的 prototype
。但a对象 prototype 默认 是 指向Object.prototype 的,
而我们在 Object.prototype
定义了say 方法,b 对象也能訪问 say()方法, 就好像b 继承了 父类中的 属性一样。
这里我们也能够看出,一旦
原型链 过长。会导致 訪问多个对象的prototype。
所以 在设计 的时候 应该 不超过 3层原型链。能够考虑其它方式。
Javascript 最佳的实践:
// 定义动物类
function Animal(type, name) {
// 定义属性
this.type = type;
this.name = name;
} // 定义方法
Animal.prototype.say = function() {
console.log('Hi,My name is %s ,I am a %s', this.name, this.type);
} // 定义Dog 类
function Dog(type, name, hobby) {
// 这里的this 指向的是新创建的dog对象,而通过 Animal.apply 形式调用 Animal方法 ,
// 显示的指定其 this ,指向新创建的dog对象 ,再把对象的參数传进去
// 所以在 Animal 构造函数中 的 代码 是 为 新创建的dog对象 的属性 赋值
// 从而实现了 属性的继承
Animal.apply(this, [ type, name ]);
this.hobby = hobby;
} Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; var d = new Dog('Dog', '大黄狗', '吃骨头');
d.say();
定义:
通过构造函数,定义 对象的 属性。
通过原型对象。定义 对象的 方法。
继承:
使用构造函数的 prototype。实现方法的继承
在构造函数使用
父类构造函数.call(this,);
父类构造函数.apply(this,[])
从而实现属性的继承。
ECMAScript 5中引入了一个新方法: Object.create. 能够调用这种方法来创建一个新对象. 新对象的原型就是调用create方法时传入的第一个參数:
谨记:Javascript 并非继承了原型对象中的属性,而是在訪问对象的属性时。依次在原型对象上訪问,
从而达到继承的效果,这就是Javascript继承的本质,所以我们仅仅需建立 对象(子对象)的原型 与 对象(父对象)的关系就可以。
不要在Object.prototype 定义不论什么内容
继承还能够有非常多种 实现方式。 比方 属性的复制等等,应当灵活运用。
Javascript继承之最佳实践的更多相关文章
- javascript编程的最佳实践推荐
推荐的javascript编程的最佳实践,摘要记录在这里: 可维护的代码保证代码的性能部署代码 1 可维护的代码1.1什么是维护的代码:可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需原 ...
- (译) 《Javascript 24条最佳实践》
(摘录) <Javascript 24条最佳实践> 自己一直偏向于实用主义,不是学院派,不是学究派,只讲究把东西能够很好的做出来,但经过一段时间的开发工作当自己总结出来一些东西时,觉得挺有 ...
- 【转】超实用的JavaScript技巧及最佳实践
众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现 ...
- 超实用的JavaScript技巧及最佳实践
众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现 ...
- 超实用的JavaScript技巧及最佳实践(上)
在这篇文章中,作者将会向大家分享JavaScript开发的小技巧.最佳实践等非常实用的内容,不管你是前端开发者还是服务端开发者,都应该来看看这些小技巧,它们绝对会让你受益的. 文中所提供的代码片段都已 ...
- JavaScript Web 应用最佳实践分析
[编者按]本文作者为 Mathias Schäfer,旨在回顾在客户端大量使用JavaScript 的最佳 Web应用实践.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 对笔者来说,Jav ...
- 超实用的JavaScript技巧及最佳实践(下)
1.使用逻辑符号&&或者||进行条件判断 1 2 3 var foo = 10; foo == 10 && doSomething(); // is the same ...
- 20个超实用的JavaScript技巧及最佳实践
1.第一次给变量赋值时,别忘记var关键字 给一个未声明的变量赋值,该变量会被自动创建为全局变量,在JS开发中,应该避免使用全局变量. 2.使用===替换== 并且永远不要使用=或!=. ...
- javaScript高程笔记--最佳实践
1.可维护性 <1>什么是可维护的代码 (1)可理解性 (2)直观性 (3)可适应性 (4)可扩展性 (5)可调试性 <2>代码约定 (1)可读性---适当的进行注释[函数和方 ...
随机推荐
- 为应用程序池“XX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误
场景 WCF应用程序部署在IIS7中,使用net.tcp协议对外给几百台客户端提供服务,应用程序池不断崩溃重启. 分析过程 在事件查看器中看到的错误信息类似于 为应用程序池“XX”提供服务的进程在与 ...
- Effective C++:条款25:考虑写出一个不抛异常的swap函数
(一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...
- Windows 2008 配置ASP+ACCESS环境(亲身体会)
我们公司OA系统是用asp开发的,时间有些长了,原来只是公司总部,部署到内网就可以了,现在要求全国各地的分公司也要用,而且接入了56短网的短信接口(http://www.56dxw.com),主要起到 ...
- Dom4j分解xml
package cn.com.guju.util; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingExc ...
- 【SICP读书笔记(四)】练习2.27 --- 表序列reverse的扩展:树结构的deep-reverse
题目要求是,修改练习2.18所做的reverse过程,得到一个deep-reverse过程.它以一个表为参数,返回另一个表作为值,结果表中的元素反转过来,其中的子树也反转. 例如: (define x ...
- spring mvc综合easyui点击上面菜单栏中的菜单项问题
采用easyui的tree报错发生的背景后,会弹出一个窗口,有一个问题是,当你点击顶部 解决方案,如下面(运用easyui1.36): /home/cyz/workspace/hb_manager ...
- Android 随着输入框控件的清除功能ClearEditText,抄IOS输入框
今天给大家带来一个非常有用的小控件ClearEditText,就是在Android系统的输入框右边增加一个小图标,点击小图标能够清除输入框里面的内容,IOS上面直接设置某个属性就能够实现这一功能.可是 ...
- c++11多线程简介
C++11开始支持多线程编程,之前多线程编程都需要系统的支持,在不同的系统下创建线程需要不同的API如pthread_create(),Createthread(),beginthread()等,使用 ...
- sql基础之DDL(Data Definition Languages)
好久没写SQL语句了,复习一下. DDL数据定义语言,DDL定义了不同的数据段.数据库.表.列.索引等数据库对象的定义.经常使用的DDL语句包含create.drop.alter等等. 登录数据:my ...
- 连接字符串中Min Pool Size的理解是错误,超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
Min Pool Size的理解是错误的 假设我们在一个ASP.NET应用程序的连接字符串中将Min Pool Size设置为30: <add name="cnblogs" ...