你不知道的JavaScript对象和包装类

什么是对象?谈谈你对对象的了解?

好吧,这个对象不是你认为的那个对象哦,现在让我们开始进入话题。 让我们先来看一个例子:

var HuaZiGe = {
    name: 'huazi',
    age: 20,
    sex: 'boy',
    smock:function(){
        console.log('I am somking! cool!')
        //HuaZiGe.health--
        this.health--
    },
    drink:function(){
        console.log('I am drink')
        //HuaZiGe.health++
        this.health++
    },
    health:100
    }
复制代码

这是一个基本的对象声明,声明一个HuaZiGe对象,该对象包含属性:name、age、sex、health,方法:smock()、drink()。

这个对象可以有哪些操作呢?

//对象里面的属性可读可写
HuaZiGe.health++ 
console.log(HuaZiGe.health)//101

//对象里面的方法可以调用,方法可读可写对象的属性
HuaZiGe.smock()//99
HuaZiGe.drink()//100
HuaZiGe.drink()//101
console.log(HuaZiGe.health)//101

//增加属性
HuaZiGe.boyFriend = 'lai'

//查找是否增加成功
console.log(HuaZiGe.boyFriend)//'lai'

//修改属性值
HuaZiGe.sex = 'girl'
console.log(HuaZiGe.sex)//'gril'

//删除属性
delete HuaZiGe.sex
delete HuaZiGe.name
Xxx(xxx).yyy
console.log(HuaZiGe.naem)// undefined  为什么不是报错?
// 这里注意:当访问一个不存在的变量时会把错,当访问一个对象不存在的属性就为undefinef

//所以接下来的操作也是输出undefined,而不是报错
console.log(HuaZiGe.like)//undefined

复制代码

上面这个对象其实是大多数人都知道的普遍的一种对象定义方式,C和java也差不多是这样写的,但是javascpipt的对象定义有两种形式,这只是其中的一种叫做 声明(文字)形式, 接下来我们来看下一种 构造形式

//这是一个构造函数 ,以首字母大写来区分普通函数 (当然它和普通函数没什么区别)
function Car(color){
    this.name = 'BMW'  //创建属性name 值为'BMW'
    this.health = 100   //创建属性health 值为100
     this.color = color //创建属性color 值为形参color的值
    this.run = function(){
    //如果不加this就会报错哦
       // health-- //health is not defined
       this.health--
    }
}

//下面进行操作:
console.log(Car())//undefined (因为构造函数没有返回值)

var car1 = new Car('pink')
 car1.run()//调用car1对象一次里面的方法,使得里面的属性health减一
console.log(car1.health)//99

var car2 = new Car('red')

console.log(car1===car2)//false 构造函数实例化出来的对象是相互独立的
 console.log(car1,car2)//从输出结果发现,car1和car2 color属性值不同,就知道car1和car2肯定不相等(根本原因:内存地址不同)

car1.name = '红旗'
car2.name = '劳斯莱斯'
car2.run()
console.log(car1,car2)
复制代码

看了你可能会有疑惑 :this怎么操作,构造函数哪来的返回值?

下面就来解释:

构造函数的内部原理:(当被new的时候)

  1. 在构造函数体内最前面隐式加上 this={}
  2. 执行 this.xxx = xxx
  3. 隐式的返回this

放入代码来解释:

//构造函数
function Student (name ,age, sex){
    // 第一点(看不到的):
    //var this = {
               //name:''
               //age:''
               //sex:''
              // }
    //第二点:
    this.name = name
    this.age = age
    this.sex = sex
    this.grade = 2019
    //第三点(也是看不到的):
    //return this
    
 
   // 如果 return的是 [](数组)、 function(){}(函数)、{}(对象),会改变return的返回值哦
}
//console.log(Student()) //undefined 函数本身没有返回值,没有new就把它当作个普通函数调用吧
var student =new  Student('帅帅',20,'boy')//只有new 后才能返回一个对象
console.log(student)
复制代码

其实构造函数也有不同的定义形式,可以用系统自带的Object()

var obj = new Object() //和var obj = {} 没有区别
复制代码

也可以自己定义:

(就是自己写一下this的运行机制.一般不建议写自定义构造函数,这样的话构造函数很多自带的东西无法运用)

function myPerson(name,age){
    var that = {}
        that.name = name
        that.age = age
        return that
}

var per1 = myPerson('帅',20)
var per2 = myPerson('家君',20)
console.log(per1,per2)
复制代码

下面我们来聊一下包装类

老规矩,上代码!

var num = 123
num.abc = 'aaa'
 console.log(num.abc)//undefined
复制代码

上面的输出为什么是undefined 而不是aaa呢? 有一条规定叫做:

原始值是不能有属性和方法,属性和方法只有对象才能有,这是对象独有的!!!

先了解原始值有哪些类型: 原始值的类型有:string、number、boolean、undefined、null等一些我们熟悉的,非原始值类型(我们叫引用类型)有:object、Array、function;

了解了这些我们就来解答上面的问题

//在原始值身上调用属性,会隐式的发生一个过程
 var num = 4
 num.len = 3
//变化过程:
//new Number(4).len = 3 ->delete num.len
//先产生一个Number对象,然后让它的属性len值为3,然后根据那条规则才判断这是一个原始值,所以删除len的值,但是它还是存在的,以后定义过了。

//相当于如下代码:
var num = new Number(4) // 类型包装
num.len = 3;
delete num.len
console.log(num.len)//undefined
复制代码

了解了上面的知识点,我们来做一道阿里的面试题吧(大家看仔细,有坑。答案我会发布在评论区)

//请问输出结果是什么?
var str = 'abc'
 str +=1
var test = typeof(str)
if(test.length == 6){
    test.sign = 'typeof的返回结果可能是String'
 
}
console.log(test.sign)

复制代码

小结:

一.对象的创建

  1. var obj = {} //plainObject 对象字面量 | 对象直接量
  2. 构造函数 //1) 系统自带的构造函数 Object() //2) 自定义

构造函数的内部原理:(当被new的时候) 1. 在构造函数体内最前面隐式加上 this={} 2. 执行 this.xxx = xxx 3. 隐式的返回this 二.包装类 1.规则:原始值是不能有属性和方法,属性和方法只有对象才能有,这是对象独有的!!! 2. 在原始值身上调用属性,会隐式的发生一个过程

Guess you like

Origin juejin.im/post/7031832848340353054