2016-09-15 58 views
2

我有一個很難理解爲什麼有一些問題,下面的代碼https://jsfiddle.net/q4w6e3n3/3/與屬性訪問器(吸氣)擴散操作問題

注:所有的例子都在Chrome版本52.0.2743.116測試只是在情況下,這有助於

const model = { 
    someVal: 'some val', 
}; 


const obs = { 
    ...model, 
    get accessor() { 
    return this.someVal; 
    }, 
} 

// Expected: '>>> some val' 
// Actual: '>>> undefined' 
console.log('>>>', obs.accessor); 

但類似如下片段工作https://jsfiddle.net/q4w6e3n3/5/

const model = { 
    someVal: 'some val', 
}; 


const obs = { 
    get accessor() { 
    return this.someVal; 
    }, 
    ...model, 
} 

// Expected: '>>> some val' 
// Actual: '>>> some val' 
console.log('>>>', obs.accessor); 

使用babel REPL我能夠看到Object.assign被使用,如果可用的傳譯代碼 當我直接使用它而不是對象傳播時,我得到同樣的問題,並且如果把model 變量放到最後在開始時。

這是一個錯誤?還是它的預期行爲?

而且爲什麼下面的代碼片段工作,以及?:

const model = { 
    someVal: 'some val', 
}; 


const obs = { 
    someVal: model.someVal, 
    get accessor() { 
    return this.someVal; 
    }, 
} 

// Expected: '>>> some val' 
// Actual: '>>> some val' 
console.log('>>>', obs.accessor); 

https://jsfiddle.net/q4w6e3n3/6/

我希望它具有相同的問題,但可以作爲一個魅力的干將this關鍵字莫名其妙地綁定到對象他們被添加到?

+1

這似乎是在transpilation的錯誤,不應該用'Object.assign'爲「自己」的屬性。你應該把它報告給插件。 – Bergi

+0

'this'對象遵循標準規則。當你像'obs.accessor'那樣調用getter時,那麼'this'將會(應該)成爲'obs'(除非它是明確綁定的,這裏不是這種情況)。事實並非如此,您將'undefined'作爲輸出,這可以通過您找到的Object.assign來解釋。在getter中添加'console.log(abs === this);'時注意不同之處。不是很好。 – trincot

+0

不確定'Object.assign'在這裏導致問題。當使用'get'語法時,上下文似乎被綁定到原始對象上,正常的方法工作得很好,如下所示https://jsfiddle.net/q4w6e3n3/8/ –

回答

1

Object.assign不會複製訪問器。所以當你的圖示在你的getter babel和它的各種voodoos使用Object.assign之前,並且accessor不會被複制到第二個好的voodoo的第一個對象上。當你的摔跤在吸氣之後,它會用吸氣劑將摔打屬性分配到對象上,並保留吸氣劑。

在這裏看到:MDN - Object.assign

相關代碼摘錄:

**Copying Accessors** 
var obj = { 
    foo: 1, 
    get bar() { 
    return 2; 
    } 
}; 

var copy = Object.assign({}, obj); 
console.log(copy); 
// { foo: 1, bar: 2 }, the value of copy.bar is obj.bar's getter's return value. 

// This is an assign function that copies full descriptors 
function completeAssign(target, ...sources) { 
    sources.forEach(source => { 
    let descriptors = Object.keys(source).reduce((descriptors, key) => { 
     descriptors[key] = Object.getOwnPropertyDescriptor(source, key); 
     return descriptors; 
    }, {}); 
    // by default, Object.assign copies enumerable Symbols too 
    Object.getOwnPropertySymbols(source).forEach(sym => { 
     let descriptor = Object.getOwnPropertyDescriptor(source, sym); 
     if (descriptor.enumerable) { 
     descriptors[sym] = descriptor; 
     } 
    }); 
    Object.defineProperties(target, descriptors); 
    }); 
    return target; 
} 

var copy = completeAssign({}, obj); 
console.log(copy); 
// { foo:1, get bar() { return 2 } }