js 包装类——str.length为什么能够执行?

108 阅读3分钟

数据类型

  • 原始类型(数字、字符串、布尔,undefined、null):值直接存在调用栈中
  • 引用类型(又叫复杂类型):值存在堆中,在调用栈里存放的只有堆里的引用地址

对象创建的三种方法

  1. 对象字面量

     var obj = {}
    
  2. 构造函数 new Object()

     var obj2 = new Object();
    

    第一和第二种方法是一样的,只是写法不同

  3. 自定义构造函数

     function Car() {    
         this.name = 'BMW'
         this.height = 1400
         this.width = 4900
         this.weight = 1000
     }
     let car = new Car(); 
    

    通过构造函数创建出来的对象叫做实例对象,实例对象可以有任意个,但相互之间是独立的个体

构造函数

构造函数在 JavaScript 中是一个重要的概念,它是一种工厂,可以用来批量生成对象。在使用 new 操作符时,构造函数会被调用,创建一个新的对象,并将该对象作为 this 关键字的上下文,然后执行构造函数中的逻辑,最后返回这个新创建的对象。

new的过程(原理):

  1. 创建this空对象

  2. 执行构造函数中的逻辑

  3. 返回this对象 (其实在第三步之前还有一步,这步与原型有关,所以在这先不讲) 例子:

     function Car() {    
             this.name = 'BMW'
             this.height = 1400
             this.width = 4900
             this.weight = 1000
         }
     let car = new Car(); 
    

    其中let car = new Car(); 的new的操作是:

    1.创建this空对象

     var this= {
     
     }
    

    2.执行构造函数中的逻辑

     var this= {
         name = 'BMW'
         height = 1400
         width = 4900
         weight = 1000    
     }
    

    3.返回this对象

     var this= {
         name = 'BMW'
         height = 1400
         width = 4900
         weight = 1000    
     }
     return this
    

包装类

我们先记住这样一句话:原始值是不能具有属性和方法的,属性和方法是对象独有的

我们来看这个例子

var num = 123
num.a = 'hello'
console.log(num.a);

按理说这个代码会报错,但执行结果却是undefined,这是为什么呢,原因是这样的。上面的代码对于V8引擎来说是这样的

var num = new Number(123)
num.a = 'hello'
//但因为原始值不具有属性和方法
delete num.a 
console.log(num.a);
//访问对象身上不存在的属性时,返回值是undefined

解释:

Number()是构造函数,他是V8自带的,像这样的构造函数还有String(),Boolean(),Object()等等。其实这就是为什么上面在创建对象的方法里讲一二两种方法是一样的,因为对于V8引擎来说这两种写法在他看来都是第二种,也就是构造函数的方法,所以这里的num其实叫num对象,对于对象来说,num.a = 'hello'就是在往这个对象里添加值,所以程序不报错。但是这个时候V8引擎才反应过来,num是一个原始值,原始值不具有属性和方法,所以这时他会自动执行delete num.a这步代码,执行完之后再去打印num.a,此时num对象已经不存在a这个属性,访问对象身上不存在的属性时,返回值是undefined。

这个时候又存在问题了,为什么当访问对象身上不存在的属性时,返回值是undefined?

其实console.log(num.a);这行代码他是在先往num对象上添加一个a属性,再去打印这个属性,所以返回值是undefined.

考点

下面这个代码能否执行,如果能,执行结果是什么

var str = 'abcd'
str.length = 2
console.log(str.length); 

答案:能,执行结果是4

实际V8的执行代码

var str = 'abcd'
str.length = 2
delete str.length
console.log(new String('abcd').length);