此处在折腾ReactJS期间,想要用到JS中的(ES6)中,给原生的String类,添加额外的isEmpty的属性
而如果是添加函数,则之前就已经见过和实现过了,比如对于原生的Date去扩展出额外的函数:
// 对Date的扩展,返回时间戳(毫秒,13位) // 例子: // this=Tue Jun 06 2017 15:00:00 GMT+0800 (CST) -> timesamp=1496732400000 Date.prototype.timestamp = function () { console.log(`Date timesamp: this=${this}`); let timesamp = this.getTime(); console.log(`this=${this} -> timesamp=${timesamp}`); return timesamp; }; |
此处,想要搞清楚,如何给原生的类中,添加额外的属性
先去搞清楚,对于String的判断字符串为空的写法:
js string is empty
null – How do you check for an empty string in JavaScript? – Stack Overflow
Javascript: How to check if a string is empty? – Stack Overflow
再去搜:
es6 class 添加属性
ES6 扩展已有类的属性
去试试:
结果:
String.prototype = { isEmpty() { let curIsEmpty = this === ”; console.log(‘String isEmpty function?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; }, get isEmpty() { let curIsEmpty = this === ”; console.log(‘String isEmpty property?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; }, }; |
出错:
Uncaught TypeError: Cannot assign to read only property ‘prototype’ of function ‘function String() { [native code] }’ at eval (string.js:25) at Object.<anonymous> (index.js?e4423b7a420df80e1047:5158) at __webpack_require__ (vendor.bundle.js?e4423b7a420df80e1047:711) at fn (vendor.bundle.js?e4423b7a420df80e1047:117) at eval (main.js:73) at Object.<anonymous> (index.js?e4423b7a420df80e1047:3017) at __webpack_require__ (vendor.bundle.js?e4423b7a420df80e1047:711) at fn (vendor.bundle.js?e4423b7a420df80e1047:117) at eval (app.js:45) at Object.<anonymous> (index.js?e4423b7a420df80e1047:2598) |
换成:
String.prototype.isEmpty = { // isEmpty() { // let curIsEmpty = this === ”; // console.log(‘String isEmpty function?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); // return curIsEmpty; // }, get isEmpty() { let curIsEmpty = this === ”; console.log(‘String isEmpty property?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; }, }; |
测试代码:
let emptyStr = ”; console.log(‘typeof(emptyStr.isEmpty)=’, typeof(emptyStr.isEmpty)); console.log(’emptyStr.isEmpty=’, emptyStr.isEmpty); console.log(’emptyStr.isEmpty()=’, emptyStr.isEmpty()); |
结果:
typeof(emptyStr.isEmpty)= object main.js:101 emptyStr.isEmpty= |
很明显,isEmpty变成一个对象,一个字典变量了。
换成:
String.prototype.isEmpty = (this === ”); |
结果:
typeof(emptyStr.isEmpty)= boolean main.js:101 emptyStr.isEmpty= false |
是bool了,但是却是错的
ES6 add existing class property
javascript – ES6 – declare a prototype method on a class with an import statement – Stack Overflow
ES6 Javascript Classes – define class method to an existing function – Stack Overflow
javascript – Extending es6 classes programmatically – Stack Overflow
es6 extend String
javascript – Extend a String class in es6 – Stack Overflow
Object.assign() – JavaScript | MDN
Object.defineProperty() – JavaScript | MDN
javascript – The error when extending String in ES6 – Stack Overflow
javascript: add method to string class – Stack Overflow
Subclassing builtins in ECMAScript 6
ES6 Everyday: Extending Built-in Classes » Logan Franken: Software Developer
试试:
Object.defineProperty(String.prototype, ‘isEmpty’, { value() { let curIsEmpty = this === ”; console.log(‘String Object.defineProperty: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; } }); |
结果:
typeof(emptyStr.isEmpty)= function main.js:101 emptyStr.isEmpty= ƒ value() { var curIsEmpty = this === ”; console.log(‘String Object.defineProperty: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; } |
也还不是bool,而是function
Object.defineProperty add property
Object.defineProperty Function (JavaScript) | Microsoft Docs
又去是了多次:
Object.defineProperty(String.prototype, ‘isEmpty’, { value: this === ” }); |
结果:
还是不对。
JavaScript ES5: Meet the Object.defineProperty() method
问题还是在于
String中this未定义
所以需要找到:
String中有哪些属性
JS properties: enumerable, writable & configurable – arqex
找到定义:
interface String { /** Returns a string representation of a string. */ toString(): string; /** * Returns the character at the specified index. * @param pos The zero-based index of the desired character. */ charAt(pos: number): string; 。。。 /** Returns the primitive value of the specified object. */ valueOf(): string; readonly [index: number]: string; } |
去试试:
Object.defineProperty(String, ‘isEmpty’, { get: () => { let curStr = this.valueOf(); let curIsEmpty = curStr === ”; console.log(‘String Object.defineProperty: curStr=’, curStr, ‘ ,this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; } }); |
问题以及:
typeof(emptyStr.isEmpty)= undefined main.js:101 emptyStr.isEmpty= undefined |
【总结】
算了,暂时不会添加属性isEmpty。
还是只能给String添加函数isEmpty():
String.prototype.isEmpty = function() { let curIsEmpty = this === ”; console.log(‘String isEmpty function?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; }; |
调用:
let emptyStr = ”; console.log(‘typeof(emptyStr.isEmpty)=’, typeof(emptyStr.isEmpty)); console.log(’emptyStr.isEmpty=’, emptyStr.isEmpty); console.log(’emptyStr.isEmpty()=’, emptyStr.isEmpty()); |
结果:
typeof(emptyStr.isEmpty)= function main.js:101 emptyStr.isEmpty= ƒ () { var curIsEmpty = this === ”; console.log(‘String isEmpty function?: this=’, this, ‘ ,curIsEmpty=’, curIsEmpty); return curIsEmpty; } string.js:78 String isEmpty function?: this= ,curIsEmpty= true main.js:102 emptyStr.isEmpty()= true |
注意:
此处如果给String.prototype.isEmpty赋值用的是箭头函数:
String.prototype.isEmpty = () => { } |
是没有用的。
具体原因,待以后深究。