javascript高级编程学习笔记(二)

写读书笔记的好处在于加深记忆,前一篇总结了编程中创建的对象的几种方式,以及常用的方式,这一篇总结实现继承的方式:
1、对象冒充:

function ClassA(sColor) {

this.color = sColor;

this.sayColor = function () {

    alert(this.color);

};

}

function ClassB(sColor, sName) {

this.newMethod = ClassA;

this.newMethod(sColor);

delete this.newMethod;

this.name = sName;

this.sayName = function () {

    alert(this.name);

};

}

var objA = new ClassA(“blue”);

var objB = new ClassB(“red”, “John”);

objA.sayColor(); //输出 “blue”

objB.sayColor(); //输出 “red”

objB.sayName(); //输出 “John”

对象冒充可以实现多重继承:

function ClassZ() {

this.newMethod = ClassX;

this.newMethod();

delete this.newMethod;

this.newMethod = ClassY;

this.newMethod();

delete this.newMethod;

}

ECMAScript 的第三版为 Function 对象加入了两个方法,即 call() 和 apply()

2、使用call()方法(与经典的对象冒充方法最相似的方法)

function sayColor(sPrefix,sSuffix) {

alert(sPrefix + **this.color** + sSuffix);

};

var obj = new Object();

obj.color = “blue”;

sayColor.call(obj, “The color is “, “a very nice color indeed.“);

里面的this.color的this就是obj

function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.call(this, sColor);

 //执行对象ClassA里面的this.color和this.sayColor语句,而且this代表传入的ClassB,这样就为ClassB添加了两个成员

this.name = sName;

this.sayName = function () {

    alert(this.name);

};

}

3、使用apply()方法

apply方法和call方法很类似,

apply方法的使用如下:

function sayColor(sPrefix,sSuffix) {

alert(sPrefix + this.color + sSuffix);

};

var obj = new Object();

obj.color = “blue”;

sayColor.apply(obj, new Array(“The color is “, “a very nice color indeed.“));

创建ClassB的时候可以使用:

(1)
function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.apply(this, new Array(sColor));

this.name = sName;

this.sayName = function () {

    alert(this.name);

};

}

(2)
function ClassB(sColor, sName) {

//this.newMethod = ClassA;

//this.newMethod(color);

//delete this.newMethod;

ClassA.apply(this, arguments);

this.name = sName;

this.sayName = function () {

    alert(this.name);

};

}

可以看到只是出入对象的参数不同而已的,使用的数组或者arguments

4、使用原型链

(1)
function ClassA() {

}

ClassA.prototype.color = “blue”;

ClassA.prototype.sayColor = function () {

alert(this.color);

};

function ClassB() {

}

ClassB.prototype = new ClassA();

(2)

function ClassB() {

}

ClassB.prototype = new ClassA();

//如果上面的这句代码(ClassB.prototype = new ClassA(); ),在下面的两句代码之后的话,那么添加的name,sayName成员都会丢失

ClassB.prototype.name = ““;

ClassB.prototype.sayName = function () {

alert(this.name);

};

所以在使用这种方式的时候要注意顺序

使用原型链的时候还可以使用instanceof:
var objB = new ClassB();

alert(objB instanceof ClassA); //输出 “true”

alert(objB instanceof ClassB); //输出 “true”

但是使用原型链的弊端是不支持多重继承,原型链会用另一类型的对象重写类的 prototype 属性。

5、混合方式

如果用对象冒充的话就必须使用构造函数方法,所以不是最好的选择,但是使用原型链的话无法使用带参数的构造函数
,比如使用原型链里面的(2)代码,ClassA如果是构造函数,那么创建对象的时候就要先执行
ClassB.prototype = new ClassA(XXX);
再执行:
ClassB.prototype.name = ““;

ClassB.prototype.sayName = function () {

alert(this.name);

};

这样是不现实的,因为你是先把ClassB的原型方法定义好了的,使用的时候要直接创建实例
,这样就不能参数传入ClassA,所以最后采用了混合方式(如下)

function ClassA(sColor) {

this.color = sColor;

}

ClassA.prototype.sayColor = function () {

alert(this.color);

};

function ClassB(sColor, sName) {

ClassA.call(this, sColor);

this.name = sName;

}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () {

alert(this.name);

};

使用这种方式的时候,可以通过创建ClassB时候传入的参数再传入到ClassA里面使用。

学习小结:

所以最常用的实现继承的方式是混合方式,有原型链也有冒充方式。
时间: 2024-11-06 08:47:45

javascript高级编程学习笔记(二)的相关文章

JavaScript高级编程(学习笔记)

一 内存分配 1,栈:由计算机管理,先进后出,快但不自由  堆:由程序员控制,自由 2,引用类型存于堆,值类型存于声明它的地方 二 垃圾回收 1,找出不再使用的变量(堆内存中,没有栈内存指向它),然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行. 2,离开作用域标记可删,大部分浏览器都是使用这种方式进行垃圾回收,区别在于如何标记及垃圾回收间隔而已 3,JavaScript对象通过标记清除的方式进行垃圾回收,但非JavaScript原

JavaScript高级程序设计学习笔记--基本概念

1.语句 ECMAScript中的语句以一个分号结尾:如果省略分号,则由解析器确定语句的结尾,如下例所示: var sum=a+b //即使没有分号也是有效的语句--推荐 var diff=a-b; //有效的语句--推荐 虽然语句结尾的分号不是必需的,但我们建议任何时候都不要省略它.两个原因:1.加上分号可以避免很多错误 2.加上分号也会在某些情况下增进代码的性能,因为这样解析器就不必再花时间 推测应该在哪里插入分号了. 2.变量 var message="hi"; 像这样初始化变量

JavaScript高级程序设计学习笔记--错误处理与调试

try-catch语句 只要代码中包含finally子句,则无论try或catch语句块中包含什么代码--甚至return语句,都不会阻止finally子句的执行,来看下面这个函数: function testFinally(){ try{ return 2; }catch(error){ return 1; }finally{ return 0; } } 调用这个函数会返回0(PS:但我实际执行的时候会先返回0,再返回2) 抛出错误 与try-catch语句相配的还有一个throw操作符,用于

JavaScript高级程序设计学习笔记--面向对象程序设计

工厂模式 虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为解决这个问题,人们开始使用 工厂模式的一种变体. function createPerson(name,age,job){ var o=new Object(); o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name); }; return o; } var

Javascript高级程序设计学习笔记

3. 基本概念 基本数据类型:Undefined,Null,Boolean,Number,String. 复杂数据类型:Object. 3.6 语句 switch比较值时用的是全等运算符 “===” ,因此不会进行类型转换.例如 “10” 不等于10. 3.7 函数 ECMAScript函数不介意传递进来多少个参数,也不在乎参数的类型.即使定义的函数只接受两个参数,在调用的时候也可以传递任意多个或者0个.因为ECMAScript的参数在内部是用一个数组表示的,在函数体内部可以通过argument

JavaScript高级程序设计学习笔记--高级技巧

惰性载入函数 因为浏览器之间行为的差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中,看看下面来自上一章的createXHR()函数. function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeo

JavaScript高级程序设计学习笔记--DOM

DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序接口). Document类型 文档的子节点 虽然DOM标准规定Document节点的子节点可以是DocumentType,Element,ProcessingInstruction或Comment,但还有两个内置的访问其子节点的快捷方式.第一个就是documnetElement属性,该属性始终指向HTML页面中的<html>元素.另一个就是通过childNodes列表访问文档元素,但通过documentElement属性则

JavaScript高级程序设计学习笔记--BOM

window对象 BOM的核心对象是window,它表示浏览器的一个实例.在浏览器中,window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMScript规定的Global对象. 全局作用域 由于window对象同时扮演着ECMAScript中Global对象的角色,因此所有在全局作用域中声明的变量.函数都会变成window对象的属性和方法.来看下面的例子: var age=29; function sayAge(){ alert(this.age); }

JavaScript高级程序设计学习笔记--引用类型

Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name,age和5.但这里的数值属性名会自动转换为字符串. 对象属性的访问:点表示法和方括号语法 alert(person["name"]); // "Nicholas" alert(person.name); // "Nicholas" 从功能上看,这两