Nodejs中String("string") !== new String("string")?

Nodejs中String(“string”) !== new String(“string”)?

方法如下。

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 回复

Node.js 中 String("string") !== new String("string")?

在 Node.js 中,String("string")new String("string") 的行为有所不同。尽管它们看起来相似,但它们实际上是不同的对象类型。这种区别可能会导致一些令人困惑的结果。

示例代码

// 使用原始字符串
const originalString = String("string");
console.log(originalString); // 输出: string
console.log(typeof originalString); // 输出: string

// 使用构造函数创建字符串对象
const objectString = new String("string");
console.log(objectString); // 输出: string [String: 'string']
console.log(typeof objectString); // 输出: object

从上面的代码中可以看到,originalString 是一个原始字符串,而 objectString 是一个字符串对象。

字符串对象的方法

为了更好地理解这个问题,我们可以通过扩展字符串原型来添加一个自定义方法 cut,该方法用于截取字符串并添加省略号。

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

var obj = ["女神", "高富帅", "屌丝"];

console.log(typeof obj[1].cut(3)); // 输出: string
console.log(obj[1].cut(3)); // 输出: 高富...

在这个例子中,obj[1] 是一个原始字符串 "高富帅"。当我们调用 cut 方法时,它会返回一个新的字符串,并且 typeof 操作符会显示结果是一个原始字符串类型(string)。

但是,如果我们尝试使用字符串对象来调用这个方法,情况会有所不同:

var obj2 = new String("女神");
console.log(typeof obj2.cut(3)); // 输出: string
console.log(obj2.cut(3)); // 输出: 女神 [String: '女...']

在这个例子中,obj2 是一个字符串对象,而不是原始字符串。虽然 cut 方法仍然可以正常工作,但其返回值仍然是一个字符串对象。

总结

  • String("string") 返回的是一个原始字符串。
  • new String("string") 返回的是一个字符串对象。
  • 在大多数情况下,直接使用原始字符串更简单、更高效。
  • 如果你确实需要使用字符串对象,确保理解其行为与原始字符串的区别。

通过这些示例代码,你可以更好地理解 String("string")new String("string") 之间的区别,并且知道如何正确地使用它们。


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属性,后来有一次在链表中需要插入字符串,然后出问题了。

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

针对你的问题“Nodejs中String(‘string’) !== new String(‘string’)?” 我们来详细探讨一下这个问题,并且解释为什么会出现这种情况。

在 Node.js 中,String("string")new String("string") 是两种不同的创建字符串的方式。前者是原始类型的字符串,而后者是通过构造函数创建的对象。这会导致它们在比较时产生不同的结果。

示例代码

// 原始类型字符串
const str1 = String("string");

// 对象类型字符串
const str2 = new String("string");

console.log(str1 === str2); // 输出 false
console.log(str1 == str2);  // 输出 false
console.log(str1);          // 输出 "string"
console.log(str2);          // 输出 String {"string"}

解释

  1. 原始类型字符串 (str1):

    • str1 是一个普通的 JavaScript 字符串,属于基本数据类型。
    • 使用 typeof 操作符会返回 "string"
  2. 对象类型字符串 (str2):

    • str2 是通过 new String() 创建的,它是一个字符串对象。
    • 使用 typeof 操作符会返回 "object"
    • 当进行严格相等性检查(===)或非严格相等性检查(==)时,两者都会返回 false,因为一个是原始类型,另一个是对象类型。

与你的问题相关的解答

现在回到你的问题中:

var obj = ["女神", "高富帅", "屌丝"];

// obj[1] 是 "高富帅" 这个字符串
console.log(typeof obj[1].cut(3)); // 输出 "string"
console.log(obj[1].cut(3));        // 输出 "高富"

这里的 obj[1] 是一个普通字符串,而不是一个字符串对象。因此,当你调用 .cut(3) 方法时,JavaScript 会自动将该字符串转换为字符串对象,从而可以调用 String.prototype 上的方法。但需要注意的是,这种方式可能会带来一些潜在的问题,比如 this 的上下文可能不符合预期。因此,建议直接使用原始类型的字符串并确保 .cut(3) 方法被正确定义和使用。

回到顶部