乐趣区

关于javascript:javascript高级程序设计学习笔记-41原始值与引用值

关注前端小讴,浏览更多原创技术文章

原始值与援用值

  • 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 的变量是涣散类型的?
  • 在拜访形式和操作形式上,原始值和援用值有什么不同?
  • 在通过变量复制时,原始值和援用值有什么不同?
  • 作为函数的参数传递时,原始值和援用值有什么不同?
  • 如何“按值传递函数的参数”?为什么援用值作为函数的参数也是按值传递而不是按援用传递的?
  • 如何判断一个原始值或援用值的具体类型?
退出移动版