Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么Object.create不';你不能为我创建一个新的列表吗?_Javascript - Fatal编程技术网

Javascript 为什么Object.create不';你不能为我创建一个新的列表吗?

Javascript 为什么Object.create不';你不能为我创建一个新的列表吗?,javascript,Javascript,我正在尝试用JavaScript创建一个构建器模式。但是我想知道为什么如果我调用Object.create两次,我会得到和以前一样的列表 这是我的密码 var filterBuilder = { filters: [], addFilter: function(options) { var filter = { 'type': 'selector', 'dimension': options.dimension, 'value': optio

我正在尝试用JavaScript创建一个构建器模式。但是我想知道为什么如果我调用
Object.create
两次,我会得到和以前一样的列表

这是我的密码

var filterBuilder = {
  filters: [],
  addFilter: function(options) {
    var filter = { 
      'type': 'selector',
      'dimension': options.dimension,
      'value': options.value
    }
    this.filters.push(filter);
    return this;
  },
  build: function() {
    return this.filters;
  }
};
如果我运行
Object.create(filterBuilder.build()
我会得到
[]
,这很好。但当我开始添加过滤器时

Object.create(filterBuilder).addFilter({dimension: '1', value: 'v'}).build();
我有一个好的过滤器

但是如果我这样做了

Object.create(filterBuilder).addFilter({dimension: '1', value: 'v'}).addFilter({dimension: '1', value: 'v'}).build();

我将得到三个过滤器,第一个是来自上一个电话。不是
对象。create
应该为我创建一个新对象吗?

原型属性是共享的,因此
过滤器
数组对于您创建的两个对象都是相同的。如果希望每个对象都有自己的
过滤器
,则必须将其添加为自己的属性(由对象而不是原型拥有的属性),即:

您也可以使用
new
执行此操作:

function FilterContainer() {
  this.filters = [];
}

FilterContainer.prototype.addFilter = function() {
  ...
};

FilterContainer.prototype.build = function() {
  ...
};

// Has its own `filters` array
new FilterContainer().addFilter(...).build();

原型属性是共享的,因此所创建的两个对象的
过滤器
数组是相同的。如果希望每个对象都有自己的
过滤器
,则必须将其添加为自己的属性(由对象而不是原型拥有的属性),即:

您也可以使用
new
执行此操作:

function FilterContainer() {
  this.filters = [];
}

FilterContainer.prototype.addFilter = function() {
  ...
};

FilterContainer.prototype.build = function() {
  ...
};

// Has its own `filters` array
new FilterContainer().addFilter(...).build();

当您多次调用
Object.create(filterBuilder)
时,会得到两个对象,它们包含对同一
过滤器
数组的引用

var b1 = Object.create(filterBuilder);
var b2 = Object.create(filterBuilder);

// now b1.filters is the _same_ object as b2.filters,
// so calling
b1.filters.push(...);

// will inevitably modify b2.filters as well.
您在这里的最佳选择是使用经典函数和原型

function FilterBuilder() {
    this.filters = [];
}

FilterBuilder.prototype.addFilter = function() { };

var builder = new FilterBuilder();
builder.addFilter();

当您多次调用
Object.create(filterBuilder)
时,会得到两个对象,它们包含对同一
过滤器
数组的引用

var b1 = Object.create(filterBuilder);
var b2 = Object.create(filterBuilder);

// now b1.filters is the _same_ object as b2.filters,
// so calling
b1.filters.push(...);

// will inevitably modify b2.filters as well.
您在这里的最佳选择是使用经典函数和原型

function FilterBuilder() {
    this.filters = [];
}

FilterBuilder.prototype.addFilter = function() { };

var builder = new FilterBuilder();
builder.addFilter();
Object.create()
采用可选的第二个参数,该参数可以定义不从原型继承的属性,因此您可以(重新)定义新创建的对象的
过滤器
属性,如下所示:

Object.create(filterBuilder, { 
  filters : { writable : true, enumerable: true, value : [] }
})

Object.create()
采用可选的第二个参数,该参数可以定义不从原型继承的属性,因此您可以(重新)定义新创建的对象的
过滤器
属性,如下所示:

Object.create(filterBuilder, { 
  filters : { writable : true, enumerable: true, value : [] }
})


因为
filter
是原型的属性,而不是新创建的对象。从该原型继承的所有对象都共享该属性。类似的情况是
对象。create
会创建一个新的空对象,该对象继承了
filterBuilder
的属性。它不会创建新数组或
过滤器
属性。因为
过滤器
是原型的属性,而不是新创建的对象。从该原型继承的所有对象都共享该属性。类似的情况是
对象。create
会创建一个新的空对象,该对象继承了
filterBuilder
的属性。它不会创建新数组或
过滤器
属性。感谢您给出明确的答案。我在某个地方读过书,我应该避免使用
new
我想这只适用于继承?这是一个好建议,视情况而定。你可以用
对象制作你自己的东西。创建
,我的目标是
MyObject.new()
,这比
新建MyObject()更好。但是使用ES6
class
和spread操作符,可以避免一些混乱和不熟悉的语法。@toy:是的,在为应从另一个对象继承的子类创建原型对象时,应该避免
new
。没有理由害怕新的任何地方。谢谢你明确的回答。我在某个地方读过书,我应该避免使用
new
我想这只适用于继承?这是一个好建议,视情况而定。你可以用
对象制作你自己的东西。创建
,我的目标是
MyObject.new()
,这比
新建MyObject()更好。但是使用ES6
class
和spread操作符,可以避免一些混乱和不熟悉的语法。@toy:是的,在为应从另一个对象继承的子类创建原型对象时,应该避免
new
。没有理由害怕
新的
任何其他地方。