以下代码仅针对name属性引发错误.可以通过name在属性中将属性指定为可写来修复它,Object.create但我试图理解为什么会发生这种情况(并且可能有更优雅的方法来修复它).
var BaseClass = function (data) {
Object.assign(this, data);
}
var ExtendedClass = function () {
BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass);
console.log(new ExtendedClass({ type: 'foo' }));
new ExtendedClass({ name: 'foo' });Run Code Online (Sandbox Code Playgroud)
小智 23
如果您在Angular+Typescript+NgRX 中遇到此错误:
您可以使用扩展运算符获取只读对象的浅拷贝以使其可读,但是根据您的情况,您可能不希望这样做。
let x = [...y];
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Redux / NgRX,则您的选择器可能会返回一个带有对存储的引用的只读对象,这在尝试通过模板绑定更改该对象属性时可能会引发异常。根据您的情况,您可以进行深层复制以删除商店引用。
let x = JSON.parse(JSON.stringify(y));
Run Code Online (Sandbox Code Playgroud)
您无法修改name函数的属性.描述符说它不是writable......
var BaseClass = function (data) {
Object.assign(this, data);
};
console.log(Object.getOwnPropertyDescriptor(BaseClass, 'name'));Run Code Online (Sandbox Code Playgroud)
但既然如此configurable,你可以使用Object.defineProperty().
var BaseClass = function (data) {
Object.assign(this, data);
};
Object.defineProperty(BaseClass, 'name', {
writable: true,
value: 'Foo'
});
console.log(BaseClass.name);Run Code Online (Sandbox Code Playgroud)
编辑
我回来了!所以......正如我之前在评论中所说,我认为我已经确定了你的问题.我的回答有点太快,并没有看到你的ES5继承是错误的.
ExtendedClass.prototype = Object.create(BaseClass);不是你想做的.这样做意味着原型ExtendedClass成为构造函数.这显然会产生意外行为.
function BaseClass(data) {
console.log(this instanceof BaseClass); // "this" is not an instance of "BaseClass"
console.log(this instanceof Function); // "this" is a function
console.log(this.name); // "this" is "BaseClass"
Object.assign(this, data);
}
function ExtendedClass() {
BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass);
new ExtendedClass({ type: 'foo' });Run Code Online (Sandbox Code Playgroud)
在您的代码中,this是一个函数并引用BaseClass.这就是为什么不允许你修改它的名字......
实际上,在JavaScript中使用继承时,通常需要以下两行:
ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;
Run Code Online (Sandbox Code Playgroud)
这是一个有效的实现:
function BaseClass(data) {
console.log(this instanceof BaseClass); // "this" is an instance of "BaseClass"
console.log(this instanceof Function); // "this" is not a function
console.log(this.name); // "this" has no name yet
Object.assign(this, data);
}
function ExtendedClass() {
BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;
var instance = new ExtendedClass({ name: 'foo' });
console.log(instance.name); // foo
console.log(BaseClass.name); // BaseClass
console.log(ExtendedClass.name); // ExtendedClassRun Code Online (Sandbox Code Playgroud)
使用 ES7+ 或 TypeScript 扩展运算符功能来克服这个问题
obj = { ...obj, name: { first: 'hey', last: 'there'} }
Run Code Online (Sandbox Code Playgroud)