随意写demo,想着修改原生String的原型指向,用来扩展String功能。使用时报错,修改未生效,输出String.prototype
发现指向没有改变,可是自己确实修改的呀?又试着修改Array对象的原型指向,还是出现相同的问题,难道是JavaScript原生类型不让修改原型指向?抱着这样的疑问才写的这篇文章?
以下代码,是发现的问题demo代码:修改String、Array的属性【prototype】未生效,修改自定义new function 生效。
/* 1.修改原生String的原型指向 未生效 */
var _proto = String.prototype;
var wrapper = {
prints() {
console.log(this);
}
}
wrapper.prototype = _proto;
String.prototype = wrapper;
let ss = new String("123");
console.log(String.prototype); // chrome控制台输出:String {"", f: ƒ, format: ƒ, constructor: ƒ, anchor: ƒ, …},node直接输出没有这么详细
ss.prints(); //报错 TypeError: ss.prints is not a function
/* 2.修改原生Array的原型指向 未生效(此处代码和上面类似,也是一样的效果) */
/* 3.自定义的new function 修改原型指向生效 */
function People() {}
console.log(People.prototype);
People.prototype = {
test() {
console.log("----");
}
}
console.log(People.prototype); // chrome控制台输出:{test: ƒ, __proto__: Object}
let peo = new People();
peo.test() // 输出 ----
难道JavaScript原生类型不让修改【prototype】属性?通过Object.getOwnPropertyDescriptor
,发现确实是的~~~
/* 1.输出String属性【prototype】描述信息 */
let desc = Object.getOwnPropertyDescriptor(String, "prototype")
console.log(desc); // { configurable: false, enumerable: false, writable: false, value: {} }
/* 2.输出自定义方法People属性【prototype】描述信息 */
function People() {}
desc = Object.getOwnPropertyDescriptor(People, "prototype")
console.log(desc); // { configurable: false, enumerable: false, writable: true, value: {} }
描述符功能:
- configurable:该属性的描述符能否被改变,同时该属性能否从对应的对象上被删除,默认为false
- enumerable:对象在被枚举时生效,默认为 false。
- value:该属性对应的值,默认为 undefined。
- writable:value值能否被赋值运算符修改,默认为false。(可是,代码中使用默认是true!!!)
注意:当configurable: false时,依据 Object.defineProperty() - JavaScript | MDN 该属性所有描述符都不能修改,可是,通过defineProperty
只能将writable从 true 改为 false ,不能从false改为true,enumerable不能修改,亲测有效!!!
属性【prototype】默认 { configurable: false, enumerable: false, writable: true, value: {} }
其他属性【】默认{ configurable: true, enumerable: true, writable: true, value: {} }
总结:之前,尽可能不要操作原生类型的原型【prototype】指向,这样会同时修改项目中其他地方使用该对象的作用域。