第一种:对象冒充
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();
objB.sayColor();
objB.sayName();
注意: 所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:
第二种: 通过Function 对象上面的call, apply方法来实现继承。
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
} 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);
};
} var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();
objB.sayColor();
objB.sayName();
第三种:原型链 prototype 属性对象。
function ClassA() {
} ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function () {
alert(this.color);
}; function ClassB() {
} ClassB.prototype = new ClassA(); ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
alert(this.name);
}; var objA = new ClassA();
var objB = new ClassB();
objA.color = "blue";
objB.color = "red";
objB.name = "John";
objA.sayColor();
objB.sayColor();
objB.sayName();
注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
实际应用中,可能混合方式:
(象冒充的主要问题是必须使用构造函数方式,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数了)
在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。这种方式同样适用于继承机制,用对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。用这两种方式重写前面的例子,代码如下:
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);
}; var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor();
objB.sayColor();
objB.sayName();
注意:在第一行突出显示的代码中,在 ClassB 构造函数中,用对象冒充继承 ClassA 类的 sColor 属性。在第二行突出显示的代码中,用原型链继承 ClassA 类的方法。由于这种混合方式使用了原型链,所以 instanceof 运算符仍能正确运行。
链接:https://www.zhihu.com/question/20289071/answer/14644278
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在javascript OOP中,我们经常会这样定义:
function cat(){
}
cat.prototype={
food:"fish",
say: function(){
alert("I love "+this.food);
}
}var blackCat = new cat;
blackCat.say();
但是如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);
所以,可以看出call和apply是为了动态改变this而出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。
用的比较多的,通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过:
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这样domNodes就可以应用Array下的所有方法了。
其他的就不提了,讲多了反而迷惑。
- JS functions are objects JS函数是对象,没什么特别的
- ... that have .call and .apply methods 这些对象只不过有call和apply两个特别的方法而已
- ... both take an object as the first argument call和apply的第一个参数是任一个对象
- ... which specifies the target where the function runs against 既函数的执行(作用)目标
function fn (a) { ... }
var obj = { ... }
// 在obj上执行fn
fn.call(obj, ...)
fn.apply(obj, ....)
作者:itlr
链接:https://www.zhihu.com/question/20289071/answer/48779872
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
function add(a, b){console.dir(this);}
function sub(a, b){console.dir(this);}
add(1,2);
"Window"
sub(1,2);
"Window"
add.call(sub, 1, 2);
"sub(a, b)"
sub.apply(add, [1, 2]);
"add(a, b)"
this和arguments理解了。这2函数apply, call就不攻自破了。
链接:https://www.zhihu.com/question/20289071/answer/62582198
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。