0基础进大厂,第6天:一场与对象的双向奔赴之旅

135 阅读4分钟

一、对象的增删改查方法

先简单创建一个对象

const obj = {
    name: 'zs',
    age: 18,
}

注意点
1、对象会先找自己有没有这个属性,如果没有,就添加,如果有,则更新属性值
2、记得[ ]里记得加''

obj.gender = '男'
obj['gender'] = '男'

delete obj.name
delete obj['name']

obj.name = 'ls'
obj['name'] = 'ls'

console.log(obj.name)
console.log(obj['name'])

对象的创建方式(3种)

1、通过字面量创建对象

let obj = {}

2、通过关键字new创建对象

let obj = new Object()

3、自定义构造函数创建对象

function Person() {}
let obj = new Person ()

构造函数

为什么需要构造函数?

当需要批量化创建对象时,使用构造函数

案例一:

下面是一个普通函数,如果甲和乙都喜欢Su7 Ultra,但是一个喜欢白色、一个喜欢黑色,怎么办?
很明显,下面的函数办不了。

function Car() {
    this.name = 'Su7Ultra'
    this.hight = '1400'
    this.len = '4800'
    this.color = 'white'
}

改进之后:将颜色作为形参传入,调用函数时在实参里输入自己需要的颜色即可。

function Car(color) {
    this.name = 'Su7Ultra'
    this.hight = '1400'
    this.len = '4800'
    this.color = color
}

同理,如果实体类是一个人呢?每个人都可能有不同的名字、不同的年龄、不同的性别。
所以,我们可以这样做:

function Person(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}
let p1 = new Person('zs', 18, '男');
let p2 = new Person('lisi', 19, '女');

什么是构造函数?

当一个函数被new调用时,我们就称之为构造函数
例如:

let obj = new Object()

重点:关键字new做了什么?

function Person(name, age, gender) {
        //声明一个空对象
        var obj = {}
        
        //让构造函数的this指向这个空对象(call()方法和关键字this后面会单独有篇文章细讲)
        Person.call(obj)
        
        //执行构造函数中的代码
        this.name = name
        this.age = age
        this.gender = gender
        
        // 实例对象的隐式原型指向构造函数显示原型(下一篇文章细讲原型)
        obj.__proto__ = Person.prototype; 
        
        // 没有返回值时,默认返回this,即obj
        return obj; 
    }

包装类(不理解没关系,你一会儿会回来看的)

  • 用户定义的字面量,会被包装成对象( 比如:new Number() )
  • 一个包装类的实例对象在参与四则运算的时候,会被拆箱成原始类型
  • 因为JS是弱类型语言,所以只有在赋值语句执行时才会判断值的类型,当值被判定为原始类型,当值被判定为原始类型时,就会自动将包装对象上添加的属性移除

学到这里了,那面试官该出场了!

问题一:

请问输出的是什么?

let num = 123  
num.a = 'aaa'
console.log(num.a)

如果你回答会报错,面试官可能会微笑一下,然后没有然后了。。。。。。
如果你回答输出的是undefined,那么面试官的兴趣可能就来了,就会问你,为什么是undefined
解释:

  • 有句古老的“谣言”,万物皆对象,说的其实就跟这道题有点关系
  • 了解一个新概念——包装类,请先往下滑,看看包装类的解释
  • 所以,执行let num = 123 时,v8会先创建一个临时对象,对象是允许挂载方法的,所以num.a = 'aaa'不会报错,但是在最后,v8会判断变量的类型,如果为原始类型,就会自动执行delete方法删除属性
  • 所以,我问你,访问对象里不存在的属性,返回值是什么?对嘛!就是undefined

    如果对于通过构造函数方法声明的变量,那它的类型就是Object,所以可以正常访问属性值
var num = new Number(123)
num.a = 'aaa'
console.log(num.a) //aaa

问题二:

这份代码合理吗?

let num = new Number(123)
console.log(num + 1)

我来回答,合理!
为什么?
因为存在 [[PrimitiveValue]]: 123,这是原始值,看包装类概念第二条
所以,在执行 num + 1时,会被拆箱成原始类型,使用原始值进行运算

image.png

判断变量的类型——typeof

看一份案例就能get到

var s = 'hello'
var s1 = new String('hello')
s1.name = 'zs'
var n = 123
var b = true
var nul = null
var sym = Symbol()

console.log(typeof s1);
console.log(typeof s);
console.log(typeof n);
console.log(typeof b);
console.log(typeof undefined);
console.log(typeof nul); //Bug
console.log(typeof sym);

image.png 不知道你发现了没有,null竟然被判断成了object
这没啥好解释,就是JS这门语言历史悠久的BUG

第二份案例,判断引用类型,都是object,具体细节请看下一篇文章——原型

var obj = {};
var arr = [];
var date = new Date();
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof date);//object

在最后,送大家一个gift

注意,我用的const

const girlFriend = new Object(personality: {
            gentle: true, 
            considerate: true, 
            kind: true, 
            intelligent: true, 
            humorous: true, 
            patience: '100%', 
            temper: none
    })