解构对象属性抛出错误:ES6代码TypeError问题的修复方法
修复ES6解构函数调用时
this丢失导致的TypeError问题 这个报错的根源很明确:当你从对象里解构出printFirstName函数并单独调用时,它原本绑定的this(也就是myObj)丢了!
原对象里的printFirstName是个方法,正常通过myObj.printFirstName()调用时,this会自动指向myObj。但解构之后,这个函数变成了一个独立的函数,直接调用的话,在严格模式下this会变成undefined,自然就找不到firstname属性了。
下面给你几种实用的修复方案,按需选择就行:
方案1:调用时手动绑定this到原对象
修改printNames函数,同时保留原对象的引用,调用时用call把this绑回去:
var myObj = {firstname: "Stevey", printFirstName() { console.log(this.firstname); }} function printNames({printFirstName, ...obj}) { printFirstName.call(obj); // 把this绑定到原对象 } printNames(myObj); // 输出: Stevey
这种方式灵活,不管传入什么对象都能正常工作,不会有耦合问题。
方案2:提前给方法绑定固定的this
如果你确定这个方法只会绑定myObj,可以在定义的时候就把this绑定死:
// 稳妥的写法:通过IIFE确保绑定到对象自身 var myObj = (function() { const obj = { firstname: "Stevey", printFirstName() { console.log(this.firstname); } }; obj.printFirstName = obj.printFirstName.bind(obj); return obj; })(); function printNames({printFirstName}) { printFirstName(); } printNames(myObj); // 输出: Stevey
如果是用ES6类的话,还可以用箭头函数作为类字段,天然绑定实例的this:
class Person { constructor() { this.firstname = "Stevey"; } // 箭头函数字段自动绑定实例this printFirstName = () => { console.log(this.firstname); } } const myObj = new Person(); function printNames({printFirstName}) { printFirstName(); } printNames(myObj); // 输出: Stevey
方案3:不单独解构函数,直接用对象调用方法
这是最直观的方式,既然解构会丢this,那干脆不解构函数,直接接收整个对象然后调用方法:
var myObj = {firstname: "Stevey", printFirstName() { console.log(this.firstname); }} // 直接接收对象,调用其方法 function printNames(obj) { obj.printFirstName(); } printNames(myObj); // 输出: Stevey
如果一定要用解构,也可以先解构对象,再用对象调用:
function printNames(obj) { const {printFirstName} = obj; printFirstName.call(obj); }
方案4:用getter返回绑定this的箭头函数
这种方式有点巧妙,在对象里定义一个getter,每次访问printFirstName都会返回一个绑定了当前对象this的箭头函数:
var myObj = { firstname: "Stevey", get printFirstName() { return () => console.log(this.firstname); } } function printNames({printFirstName}) { printFirstName(); } printNames(myObj); // 输出: Stevey
不过这种方式每次访问都会创建新函数,性能上略逊一点,适合小场景使用。
内容的提问来源于stack exchange,提问作者Krishnan Ravikumar
相关产品推荐
相关产品推荐

