JS 基础(二):原型与原型链、this的应用场景

JS 基础进阶

一、js基础语法

1.1 数据类型

typeof能检测哪些类型?
何时使用全等于,何时使用等于?
值类型和引用类型的区别?

1.1.1 es6值类型和引用类型

常见值类型:number、string、boolean、undefined、Symbol(‘s’)
常见引用类型:对象、数组、null(特殊引用类型,指向空指针)、函数(特殊引用类型 ,但不用于存储数据)

可通过typeof函数检测出具体的值类型和引用类型,
其中对象、数组和null通过typeof函数检测时只能检测出object对象,但无法指出具体属于哪一类;

值类型变量在赋值时两个变量指向不同的内存地址,进行的是深拷贝
引用类型变量在赋值时指向同一个内存地址,进行的是浅拷贝

a=1;b=a;b=2;console.log(a) 											//1  深拷贝
a={
   'name':'zhangsan','age':18}; b=a; b.age=19;console.log(a.age);  	//19 浅拷贝
  1. 深拷贝代码:
/**
 * 深拷贝
 */
const obj1 = {
   
    age: 20,
    name: 'xxx',
    address: {
   
        city: 'beijing'
    },
    arr: ['a', 'b', 'c']
}

const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj = {
    }) {
   
    if (typeof obj !== 'object' || obj == null) {
   
        // obj 是 null ,或者不是对象和数组,直接返回
        return obj
    }

    // 初始化返回结果
    let result
    if (obj instanceof Array) {
   
        result = []
    } else {
   
        result = {
   }
    }

    for (let key in obj) {
   
        // 保证 key 不是原型的属性
        if (obj.hasOwnProperty(key)) {
   
            // 递归调用!!!
            result[key] = deepClone(obj[key])
        }
    }

    // 返回结果
    return result
}

1.1.2 let定义变量与var定义变量的区别:

let定义的变量可在各个块作用域中使用,而var定义的变量只能在全局作用域中使用==
注意下面代码中变量i的作用域

let a
for (let i = 0; i < 10; i++) {
   
    a = document.createElement('a')
    a.innerHTML = i + '<br>'
    a.addEventListener('click', function (e) {
   
        e.preventDefault()
        alert(i)
    })
    document.body.appendChild(a)
}

1.1.3 堆栈模型

堆栈模型:值类型一般在栈中存储,引用类型一般在堆中存储
在这里插入图片描述

1.2 Symbol ,表示独一无二的值。

Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

let s = Symbol()

typeof s
// "symbol"

变量s就是一个独一无二的值。typeof的结果说明s是 Symbol 数据类型。
既然是独一无二的,那么两个Symbol()就一定是不相等的:

let s1 = Symbol()
let s2 = Symbol()
console.log(s1)
console.log(s2)
console.log(s1 === s2) // false

注意
==Symbol函数前不能使用new命令,否则会报错。==这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

1.2.1 Symbol.for()

Symbol.for() 接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。

let s1 = Symbol.for('foo')
let s2 = Symbol.for('foo')
console.log(s1 === s2) // true

注意
Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。

Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。

const s1 = Symbol(
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值