使用 .call() 和原型继承的区别
Difference between inheriting using .call() and prototype
我最近在学习 javaScript 并且偶然发现了这个
function Polygon() {
this.dimensions = "2d";
this.print = function () {
console.log(" 2d dimensions are easy to work with!");
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
var quad = new Quad();
quad.print();
function Polygon1() {}
Polygon1.prototype.dimensions = "2d";
Polygon1.prototype.print = console.log("2d dimensions are not difficult to work with!");
function Quad1() {
this.sides = 4;
}
Quad1.prototype = Object.create(Polygon1.prototype);
Quad1.prototype.constructor = Quad1;
var quad1 = new Quad1();
quad1.print();
在这两种情况下我都可以调用打印函数,那么这两种继承方式有什么区别,或者我在这里做错了什么?
在JavaScript中,它是关于对象所有权的。 Object.call 不是永久的所有权更改,它本质上是 "calls" 另一个函数,所有权设置为该调用的调用函数,因此将其自己的属性(由 this
定义)传递给"owned" 函数。
例如
function Polygon() {
this.sides = 2;
this.dimensions = "2d";
var _this = this;
this.print = function () {
console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
new Quad().print();
// Outputs: 2d dimensions are easy to work with!, sides: 4
通过调用 Polygon.call
,将 this
作为 属性,它将 Polygon 的 this
引用替换为来自 Quad 的 this
,但仅在调用范围,本质上是将对 Polygon 中的 this
所做的更改复制到 Quad this
.
参见以下示例:
function Polygon(sides) {
this.sides = sides;
this.dimensions = "2d";
var _this = this;
this.print = function () {
console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
const poly = new Polygon(2);
const quad = new Quad();
quad.print(); // 2d dimensions are easy to work with!, sides: 4
poly.print(); // 2d dimensions are easy to work with!, sides: 2
poly.print !== quad.print; // should return true
使用 Object.prototype 是不同的,因为您是直接修改对象,而使用 Call,您是在单独调用时调用具有隐含所有权的函数。这两个示例的不同之处在于,原型示例直接在 Quad 对象上创建了一个 Polygon 实例,而 Call 从未明确地这样做。
两个方向各有优缺点、不同的测试方法等
我最近在学习 javaScript 并且偶然发现了这个
function Polygon() {
this.dimensions = "2d";
this.print = function () {
console.log(" 2d dimensions are easy to work with!");
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
var quad = new Quad();
quad.print();
function Polygon1() {}
Polygon1.prototype.dimensions = "2d";
Polygon1.prototype.print = console.log("2d dimensions are not difficult to work with!");
function Quad1() {
this.sides = 4;
}
Quad1.prototype = Object.create(Polygon1.prototype);
Quad1.prototype.constructor = Quad1;
var quad1 = new Quad1();
quad1.print();
在这两种情况下我都可以调用打印函数,那么这两种继承方式有什么区别,或者我在这里做错了什么?
在JavaScript中,它是关于对象所有权的。 Object.call 不是永久的所有权更改,它本质上是 "calls" 另一个函数,所有权设置为该调用的调用函数,因此将其自己的属性(由 this
定义)传递给"owned" 函数。
例如
function Polygon() {
this.sides = 2;
this.dimensions = "2d";
var _this = this;
this.print = function () {
console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
new Quad().print();
// Outputs: 2d dimensions are easy to work with!, sides: 4
通过调用 Polygon.call
,将 this
作为 属性,它将 Polygon 的 this
引用替换为来自 Quad 的 this
,但仅在调用范围,本质上是将对 Polygon 中的 this
所做的更改复制到 Quad this
.
参见以下示例:
function Polygon(sides) {
this.sides = sides;
this.dimensions = "2d";
var _this = this;
this.print = function () {
console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
}
}
function Quad() {
Polygon.call(this);
this.sides = 4;
}
const poly = new Polygon(2);
const quad = new Quad();
quad.print(); // 2d dimensions are easy to work with!, sides: 4
poly.print(); // 2d dimensions are easy to work with!, sides: 2
poly.print !== quad.print; // should return true
使用 Object.prototype 是不同的,因为您是直接修改对象,而使用 Call,您是在单独调用时调用具有隐含所有权的函数。这两个示例的不同之处在于,原型示例直接在 Quad 对象上创建了一个 Polygon 实例,而 Call 从未明确地这样做。
两个方向各有优缺点、不同的测试方法等