如何将带有 ES6 Rest 的方法添加到 JS 对象[重复]

Posted

技术标签:

【中文标题】如何将带有 ES6 Rest 的方法添加到 JS 对象[重复]【英文标题】:How to add a method with ES6 Rest to a JS object [duplicate] 【发布时间】:2016-08-09 08:24:42 【问题描述】:

我有一个 Person 构造函数,我想添加一个应该添加朋友的方法。我想让我的用户传递可变数量的朋友,所以我想到了 ES6 的新“休息”功能。遗憾的是,我找不到出路。这是我的第一次尝试(错误:“Uncaught TypeError: f.addFriends is not a function(...)”):

// Persons creator
function Person(name)
    this.name = name;
    this.friends = [];
    this.addFriends = function(...a)
      a.forEach(function(d)this.friends.push(d));
    


// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);

我也试过下面的代码(没有错误,但是没有加好友):

// Persons creator
function Person(name)
    this.name = name;
    this.friends = [];


Person.prototype.addFriends = function(...a)
   a.forEach(function(d)this.friends.push(d));



// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);

我做错了什么? 非常感谢您的帮助!

【问题讨论】:

你的两个 sn-ps 都为我工作(即不要抛出你描述的错误) 【参考方案1】:

forEach 接受回调,通常在全局上下文中调用(浏览器中的window)。您需要将当前的this 作为第二个参数传递给forEach

或者可以完全避免整个this 问题,而只需concat 数组:

function Person(name)
    this.name = name;
    this.friends = [];
    this.addFriends = function(...a)
      this.friends = this.friends.concat(a);
    

【讨论】:

有一个比使用 concat 更好的解决方案,看看我的回答。顺便说一句,您的代码具有替换原始数组而不是增加它的副作用。 不幸的是,您的解决方案创建了嵌套数组而不是单个数组。是的,这确实用新数组替换了当前数组。大多数时候,这应该不是问题。请参阅 Bergi 的评论以修复您的代码。【参考方案2】:

this,在传递给forEach的回调中,是不是这段代码中你的Person实例:

Person.prototype.addFriends = function(...a)
   a.forEach(function(d)this.friends.push(d));

您可以使用新的箭头函数来获得正确的上下文:

Person.prototype.addFriends = function(...a)
   a.forEach((d) => this.friends.push(d));

但这里有一个更优雅的解决方案:

Person.prototype.addFriends = function(...a)
   this.friends.push(...a);

【讨论】:

你的意思可能是.push(...a)【参考方案3】:

由于您在 forEach 中使用回调,因此 this 不引用该对象。将回调绑定到this

Person.prototype.addFriends = function(...a)
   a.forEach(function(d)this.friends.push(d).bind(this));

由于我们使用的是 ES6,因此您可以使用 arrow function 代替。箭头函数在词法上绑定 this 值:

Person.prototype.addFriends = function(...a)
   a.forEach((d) => this.friends.push(d));

【讨论】:

非常感谢您的完美回答 Ori! 不客气,虽然我必须说 nils 和 Denys 的答案更优雅。 “箭头函数自动绑定到当前上下文” 箭头函数有自己的上下文。 this 取自封闭环境,仅此而已。 这个想法是“箭头函数自动将此绑定到当前上下文”,但我发现我当前的编辑更好地反映了它。【参考方案4】:

您可以使用 ECMAScript 6 中的新功能 ->

    定义你的类:

    类人

    constructor(name) 
        this.name = name;
        this.friends = [];
    
    
    addFriends(friends) 
        // do someting with friends
        this.friends = friends
    
    

然后你就可以创建 Person 的新实例了

var p = new Person("Jack");

并添加一些新朋友

p.addFriends(....)

【讨论】:

以上是关于如何将带有 ES6 Rest 的方法添加到 JS 对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有自定义标头的任意 JSON 数据发送到 REST 服务器?

如何使用 HttpClient 将带有 JSON 的 DELETE 发送到 REST API

如何使用 React.js + Django Rest Framework 保存带有表单提交的 blob 文件

ES6数组扩展运算符(Rest+Spread)类方法原型方法

将 REST 添加到 Django [关闭]

ES6丨前端进阶基础 二,ES6rest参数,Symbol第七种数据类型