这两种函数方法有什么区别??

第一种:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.add= function () {
  return this.x
};

var p = new Point(1, 2);

第二种:

function point2(x,y){
  var o = {};
  o.x = x;
  o.y = y;
  o.add= function(){
    return o.x
  }
  return o
}

var p1 = point2(1,2)

请问两者之间的差异?

阅读 4k
9 个回答

谢邀,:))

第一种和第二种主要有个区别。

先看第二种:

// 注意 `point2` 已改为大写
function Point2(x, y) {
  var o = {};
  o.x = x;
  o.y = y;
  
  o.add = function () {
    // 注意 `o.x` 已改为 `o.x + o.y`
    return o.x + o.y;
  }
  return o;
}

var p1 = Point2(1, 2);
var p2 = Point2(1, 2);

这种方法非常好理解,但是有两个缺陷:

  1. 每个由 Point2 创建的实例都有各自的 add 方法,这就需要注意两个地方:

    1. 需要更多的内存,因为 p1.add !== p2.add, 它们各有一份内存
    2. 改变(如果存在)或者增加(如果不存在) Point2.prototype.add, 不会影响 p1p2 以及其他实例。当然,改变 p1.add 更不会影响 p2.add
  2. p1 instanceof Point2 === false(而不是true!!!!), 但是 p1 instanceof Object === true.

再看第一种方法:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.add= function () {
  // 注意 `this.x` 已改为 `this.x + this.y`
  return this.x + this.y;
};

var p1 = new Point(1, 2);
var p2 = new Point(1, 2);

这种方法比较难理解的地方是 new

var p1 = new Point(1, 2);
// 相当于:
var p1 = (function(){
  var o = Object.create(Point.prototype);
  Point.apply(o, arguments); // 在这里相当于 `o.x = 1; o.y = 2;`
  return o;
})(1, 2);

这跟上面的方法有两个不同的地方:

  1. 每个由 Point 创建的实例共享同一个 add 方法(所以更节省内存),即是 p1.add === p2.add, 这需要注意,如果改变 Point.prototype.add, 是会影响到所有实例(包括 p1, p2...)的,但是改变 p1.add 不会影响到
    p2.add.
  2. p1 instanceof Point === true, p2 instanceof Point === true (都不是false!!!!)

第一种因为是在原型对象上添加 add() ,好处就是节约内存,所有实例共享一个 add()
第二种就是每次调用point2(),都会重新申请一块内存用来创建 add()

prototype是原型,原型上的变量,可以被所有point的子类公用,共同修改。而point内部的方法,我记得js高程里叫实例对象,每个子类各自拥有一份,互不干扰。
去看看js高程里第六章第三节,她们的区别,在继承的时候,显示的会很明显

这个很明显涉及到面向对象的几种模式, 第一种是 构造函数+原型 模式;第二种是 工厂模式.至于有何差异,这是度娘级别的问题.

第一种方式中,在prototype中的属性和方法是所有的对象共享的,只创建一次;

而第二种方式中,x, y, add都是每个对象独有的,即每创建一个对象,add就会创建一次。

相对来说,第一种方式比较好,属性独有,方法放在prototype中。

关于prototype,你可以参考下这篇文章: https://www.xiabingbao.com/ja...

问题涉及到js中的对象创建问题,在高程书中P144有详细描述

第二种属于工厂模式创建对象,书中有详细描述

clipboard.png

第一种属于构造函数和原型的组合形式

clipboard.png

第一种形式是最为经典的自定义对象模式,建议看一下高程本节

第一种比较好。

一个是普通函数,一个是构造函数,构造函数在创建时,会绑定this指向,而普通函数不会

原型,度娘或者高程3里面有解答

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题