String("string") !== new String("string")?
发布于 12 年前 作者 JacksonTian 9799 次浏览 最后一次编辑是 8 年前

方法如下。

String.prototype.cut = function (len) {
  return this.length > len ? this.substring(0, len) + '...' : this;
};

然后问题来了:

var obj = ["女神", "高富帅", "屌丝"];
console.log(typeof obj[1].cut(3)); //猜猜这里打印什么?
console.log(obj[1].cut(3)); //猜猜这里打印什么?

答对了奖励棒棒糖。

17 回复
console.log(typeof obj[1].cut(3)); //object
console.log(obj[1].cut(3));//{ '0': '高', '1': '富', '2': '帅' }

String类型(仅仅指字符串var string = “高富帅”;)是一种基本类型,即字符串,基本类型没有substring等这些方法,这是字符串的包装类型(引用类型var string = new String(“高富帅”)。 我是一个Java后端,这也是我学习node(或者说javascript)比较苦恼的地方,怎么一个String 又是基本类型,又是引用类型。后来才知道,为了方便操作在背后会创建一个对应的包装类型的对象,从而可以很方便的调用substring这样的方法来操作数据。 基本数据类型有Undefined、Null、Boolean、Number、String,Undefined和Null不需要啥操作,所以包装类型就只有Boolean、Number、String。 String可以这样操作,

var string = "高富帅";
console.log(obj[1]);

支持这种可以用索引来访问字符串中的字符(EC5中定义,IE6 7不支持), 基本类型没有prototype原型对象,String包装类才有; 所以在cut方法内部已经不是调用"高富帅"这个基本类型,这里的this是一个包装类型一个object { ‘0’: ‘高’, ‘1’: ‘富’, ‘2’: ‘帅’ }

基本类型和引用类型的最大区别就是对象的生命周期,手动new出来引用类型的实例一直存在,在基本类型背后自动生成的在代码执行了就立即销毁了;无法给基本累in个添加属性和方法,只能给手动new出来的添加,可以测试下面的代码:

var s1 ="女神";
s1.adj = "美丽的";
console.log(s1.adj);
var s2 = new String("屌丝");
s2.adj = "矮搓的";
console.log(s2.adj);

String(“string”) !== new String(“string”) 这个也是前些天的学习内容,这两个是有区别的,一个是构造函数(有new的)(java程序员会对javascript的构造函数很纠结,我貌似已经超脱了…),一个是转型函数(无new的):

var s = "高富帅";
var string = String(s);
console.log(typeof string);//string
console.log(string instanceof String);//false

var object = new String(s);
console.log(typeof object);//object
console.log(object instanceof String);//true

调用Object构造函数也会自动转型(转成包装类型)

var obj = new Object(s);
console.log(obj instanceof String);//true

还有尽量不要用显示的调用包装类型构造,javascript和java中的基本类型和包装类型不一样,javascript是在背后偷偷摸摸的完成,不容易分清现在调用的到底是处理基本类型还是包装类型(引用类型)。String在java中就是引用类型,不是基本类型。

自己发的回复不可以修改哇…发了一条又一条…

扩展字符串的原型方法时,首先需要注意的就是返回 this 的情况,必须 String(this)。

必须的原因在上面可以找到

老往原型链上去查找是不是也很费性能啊

另:麻烦请教,如果想面向对象,又不想面向构造(每次调用都会解析和编译)、面向原型(查找属性或方法太远),该怎么写啊?

这个好像叫包装类型吧,js 中特有的,使用完毕,马上把类给释放了

原型链省内存,费查找。类模板费内存,省查找时间。

查找不可怕,可怕的是重复查找。解决重复查找的一个好方案就是临时引用。将查找结果保存起来。

这个问题之前遇到过,当时做一个链表,直接给插入进去的值设置next属性,后来有一次在链表中需要插入字符串,然后出问题了。

@Jackson 恩,知道了,谢谢~

@leolovenodejs 我都用命名空间,1个文件仅1个全局变量,这也方便把多个文件组织在一个变量里;用类模版可能又会涉及继承,而JS继承属实现继承,而非接口继承。

String(“string”) !== new String(“string”) 这个为true的原因是由!==这个符号引起来的,它的意思和!=是不一样的。 !==意思是左右两个不是绝对相等的,对于引用类型来说,只要引用地址不相等,上述语句就是true,而不是false ===意思是左右两个是绝对相等的,对于引用类型来说,必须引用同一个对象,只要引用地址不相等,哪怕值相同,上述语句也是false 而!=的意思是左右两个相对相等,对于引用类型来说,引用地址虾米的不重要,只要值不相等,上述语句就是true,而String(“string”) != new String(“string”)左右两边值是相等的,都是"string",所以这句为false,String(“string”) == new String(“string”)为true

js的一些经典陷阱

typeof String('string') // string
typeof new String('string') // object
new String('string') === new String('string') // false
String('string') === String('string') // true
回到顶部