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 定义不论什么内容

继承还能够有非常多种 实现方式。 比方 属性的复制等等,应当灵活运用。

时间: 2024-10-22 15:27:27

Javascript继承之最佳实践的相关文章

Javascript继承的最佳实践

什么是继承? 继承是面向对象最显著的一个特性.继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力. 在Javascript 中 没有 类的概念, 它是通过构造函数来产生 对象, 构造函数 就是一个普通的函数,通常当函数名 为 大写开头的,我们认为是构造函数,否则 就是普通的方法. function A() { this.name = 'A Class instance'; } function m1() { } 既然 Javascript 是 通过构造函数来产生

超实用的JavaScript技巧及最佳实践

众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现,比如NodeJS.Wakanda以及其它实现.此外,许多开发者都会把JavaScript选为入门语言,使用它来做一些弹出窗口等小东西. 在这篇文章中,作者将会向大家分享JavaScript开发的小技巧.最佳实践等非常实用的内容,不管你是前端开发者还是服务端开发者,都应该来看看这些小技巧,它们绝对会

【转】超实用的JavaScript技巧及最佳实践

众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现,比如NodeJS.Wakanda以及其它实现.此外,许多开发者都会把JavaScript选为入门语言,使用它来做一些弹出窗口等小东西. 在这篇文章中,作者将会向大家分享JavaScript开发的小技巧.最佳实践等非常实用的内容,不管你是前端开发者还是服务端开发者,都应该来看看这些小技巧,它们绝对会

超实用的JavaScript技巧及最佳实践(下)

文中所提供的代码片段都已经过最新版的Chrome 30测试,该浏览器使用V8 JavaScript引擎(V8 3.20.17.15). 1.使用逻辑符号&&或者||进行条件判断 1 2 3 var foo = 10;   foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();  foo == 5 || doSomething(); // is the same thi

javascript的一些最佳实践

一.缓存需要多次读取的 DOM元素,对象属性,数组值 var obj = { arr: [1, 2, 3] }; A: for (var i = 0; i < obj.arr.length; i++) { document.getElementById("Grid" + obj.arr[i]).Condition = ''; document.getElementById("Grid" + obj.arr[i]).DataBand(); } B: var ar

201508181508_《JavaScript单例模式的最佳实践(摘自汤姆大叔)》

var SingletonTester = (function () { //参数:传递给单例的一个参数集合 function Singleton(args) { //设置args变量为接收的参数或者为空(如果没有提供的话) var args = args || {}; //设置name参数 this.name = 'SingletonTester'; //设置pointX的值 this.pointX = args.pointX || 6; //从接收的参数里获取,或者设置为默认值 //设置po

【译】JavaScript 创建对象: 方法一览与最佳实践

本文是我在众成翻译上认领并翻译的:JavaScript 创建对象: 方法一览与最佳实践 在JavaScript中“创建对象”是一个复杂的话题.这门语言提供了很多种创建对象的方式,不论新手还是老手都可能对此感到无所适从,不知道应该选择哪一种.不过,尽管创建对象的方法很多,看上去语法差异也很大,但实际上它们的相似性可能比你所以为的要多.本文将带领你踏上一段梳理对象创建方法的旅程,为你揭示不同方法之间的依赖与递进关系. 对象字面量 我们的第一站毫无疑问就是创建对象最简单的方法,对象字面量.JavaSc

Javascript模块化编程(一)模块的写法最佳实践六、输入全局变量 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。 为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块但是,Javascript不是一种模块化编程语言,它不支持类class,更遑论模块module了 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂.网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑. Javascript模块化编程,已

45个实用的JavaScript技巧、窍门和最佳实践

如你所知,JavaScript是世界上第一的编程语言,它是Web的语言,是移动混合应用(mobile hybrid apps)的语言(比如PhoneGap或者Appcelerator),是服务器端的语言(比如NodeJS或者Wakanda),并且拥有很多其他的实现.同时它也是很多新手的启蒙语言,因为它不但可以在浏览器上显示一个简单的alert信息,而且还可以用来控制一个机器人(使用nodebot,或者nodruino).掌握JavaScript并且能够写出组织规范并性能高效的代码的开发人员,已经