最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《javascript高级程序设计》学习笔记 | 4.1.原始值与引用值

    正文概述 掘金(simon9124)   2021-03-01   626

    原始值与引用值

    • JS 变量是松散类型的:① 不必规定变量的数据类型 ② 变量的值和数据类型可随时改变
    • JS 变量可以包含 2 种类型的数据:原始值引用值
      • 原始值是简单数据(6 种原始值:Undefined、Null、Boolean、Number、String、Symbol),按值访问,操作实际值
      • 引用值是保存在内存中的对象,按引用访问,操作对该对象的引用(而非对象本身)

    相关代码 →

    动态属性

    • 对于引用值,可以随时添加、修改、删除其属性和方法
    let personRefer = new Object() // 创建对象
    personRefer.name = 'Nicholas' // 添加属性并赋值
    console.log(personRefer.name) // 'Nicholas'
    
    • 对于原始值,不能拥有属性(尝试添加属性不会报错)
    let namePrim = 'Nicholas' // 原始值
    namePrim.age = 27 // 给原始值添加属性
    console.log(namePrim.age) // undefined,不报错但无效
    
    • 用 new 关键字创建原始值包装类型对象,属于(类似于原始类型的)特殊引用类型
    let name1 = 'Nicholas' // 原始类型
    let name2 = new String('Matt') // 原始值包装类型
    name1.age = 27
    name2.age = 26
    console.log(name1.age) // undefined,原始类型不能有属性
    console.log(name2.age) // 26,引用类型可以有属性
    console.log(typeof name1) // string,原始类型
    console.log(typeof name2) // object,引用类型
    

    复制值

    • 原始值复制时,新值是旧值的副本,新值和旧值相互独立使用、互不干扰
    let num1Prim = 5
    let num2Prim = num1Prim
    console.log(num2Prim) // 5,原始值,复制的值是副本
    num2Prim = 6 // 副本发生改变
    console.log(num2Prim) // 6
    console.log(num1Prim) // 5,被复制的值无变化
    
    • 引用值复制时,新值和旧值共同指向堆内存中的同一个对象,新值或旧值发生改变相互影响
    let obj1Refer = new Object()
    let obj2Refer = obj1Refer // 引用值,复制的值是指针
    obj2Refer.name = 'Nicholas' // 一个对象发生改变
    console.log(obj2Refer.name) // 'Nicholas'
    console.log(obj1Refer.name) // 'Nicholas',影响另一个对象
    delete obj1Refer.name // 一个对象发生改变
    console.log(obj1Refer.name) // undefined
    console.log(obj2Refer.name) // undefined,影响另一个对象
    

    传递参数

    • ECMAScript 中所有函数的参数都是按值传递的——函数外的值被复制到函数内部的参数时,和一个变量复制到另一个变量一样:
      • 原始值作为参数时,函数内部改变参数,函数外的值不受影响
      • 引用值作为参数时,函数内部改变对象的属性,函数外的对象受影响
    /* 原始值作为参数 */
    let count = 10 // 函数外,原始值作为参数
    function addTen(num) {
      num += 10 // 函数内,参数的值发生改变
      return num
    }
    let result = addTen(count)
    console.log(result) // 30
    console.log(count) // 20,未受影响
    
    /* 引用值作为参数 */
    let person = new Object() // 函数外,引用值作为参数
    function setName(obj) {
      obj.name = 'Nicholas' // 函数内,obj和外部参数person指向同一个对象,并改变了这个对象的属性
    }
    setName(person)
    console.log(person.name) // 'Nicholas',受影响
    
    • 尽管用引用值作为参数时,函数内部改变对象的属性会影响函数外的对象,但参数仍然是按值传递的,而不是按引用传递
      • 引用值作为参数时,如果在函数内部重写对象,函数外的对象不受影响,原始的引用仍然没变
      • 如果是按引用传递,重写函数内的对象参数后,原始引用应当发生改变
    let person2 = new Object()
    function setName2(obj) {
      obj.name = 'Nicholas' // 改变参数的属性,参数受影响
      obj = new Object() // 重写参数,参数不受该影响
      obj.name = 'Greg'
    }
    setName2(person2)
    console.log(person2.name) // 'Nicholas'
    

    确定类型

    let str = 'Nicholas'
    let num = 30
    let boo = true
    let u
    let n = null
    let sym = Symbol()
    let f = new Function()
    let o = new Object()
    let a = new Array()
    let r = new RegExp()
    
    • typeof 操作符可检测的类型:String、Number、Boolean、Symbol、Undefined、Function(不包含 Null 的所有原始值和 Function)
    console.log(typeof str) // string,原始值
    console.log(typeof num) // number,原始值,原始值
    console.log(typeof boo) // boolean,原始值
    console.log(typeof u) // undefined,原始值
    console.log(typeof sym) // symbol,原始值
    console.log(typeof f) // function,引用值但是Function会返回function
    
    • typeof 操作符检测任何引用值或 null,结果都是 object
    console.log(typeof n) // object,原始值但是Null会返回object
    console.log(typeof o) // object,除Function之外的引用值都返回object
    console.log(typeof a) // object,除Function之外的引用值都返回object
    console.log(typeof r) // object,除Function之外的引用值都返回object
    
    • instanceof 操作符可检测的类型:Object(所有引用值)
    console.log(o instanceof Object) // true,o是Object的实例
    console.log(f instanceof Function) // true,f是Function的实例
    console.log(f instanceof Array) // false,f不是Array的实例
    console.log(a instanceof Array) // true,a是Array的实例
    console.log(r instanceof RegExp) // true,r是RegExp的实例
    
    • 所有引用值都是 Object 的实例
    console.log(f instanceof Object) // true,所有引用类型都是Object的实例
    console.log(a instanceof Object) // true,所有引用类型都是Object的实例
    console.log(r instanceof Object) // true,所有引用类型都是Object的实例
    
    • instanceof 操作符检测任何原始值,结果都是 false
    console.log(n instanceof Object) // false,原始值不是对象,不是Object的实例
    

    总结 & 问点

    原始值引用值
    简单数据保存在内存中的对象按值访问按引用访问操作实际值操作对该对象的引用(而非对象本身)不能拥有属性随时增、删、改其属性和方法复制的值是副本,相互不影响复制的值是指针,相互影响作为参数时,函数内部改变值不影响参数作为参数时,函数内部改变属性会影响参数,重写不影响typeof 判断类型(null 返回 object)instanceof 判断类型
    • 如何理解 JS 的变量是松散类型的?
    • 在访问方式和操作方式上,原始值和引用值有什么不同?
    • 在通过变量复制时,原始值和引用值有什么不同?
    • 作为函数的参数传递时,原始值和引用值有什么不同?
    • 如何“按值传递函数的参数”?为什么引用值作为函数的参数也是按值传递而不是按引用传递的?
    • 如何判断一个原始值或引用值的具体类型?

    起源地下载网 » 《javascript高级程序设计》学习笔记 | 4.1.原始值与引用值

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元