JavaScript study notes (eight) data types

1, the data type

(1) six data types

There are six data types JavaScript, are Number, String, Boolean, Null, Undefined and Object

In addition to the Object is a reference type, the rest are primitive types (also called base type), which is more particularly Undefined Null and two

(2) memory model

When a method execution, will create a memory stack, this method defined variables are placed on the stack, the method call is completed, the stack immediately destroyed

Is a value stored in the stack of primitive type and reference type reference variable, the value of the reference variable to an object in the heap memory address

When an object is created, a reference variable is stored on the stack, the object itself is stored in the heap, that object is not with the end of the method call are destroyed

Actually destroying the object is determined by the garbage collection mechanism, only when the object is not referenced by any reference variables, it will be destroyed

(3) are passed by value

All function arguments are passed by value in JavaScript, but due to memory models, there will be some interesting behavior

  • When we modify the basic variables in a function does not modify the incoming values

  • When we modify the reference variable in the function, it will modify the incoming values ​​(according to the interpretation of memory model, think about why)

let number = 123 // 基本类型
let object = { // 引用类型
    name: 'Steve',
    age: 18
}

function changeNumber(num) {
    num = 456
}

function changeObject(obj) {
    obj.age = 20
}

changeNumber(number)
changeObject(object)

console.log(number)
console.log(object.age)

/*
 * 执行结果:
 * 123
 * 20
**/

2, the type of detection

(1)typeof

For detecting the type of a variable, it is noted that, for a variable of type array and null, typeof return object

In addition, typeof returns the object for almost all types of objects are, that can not be used typeof accurately determine an object type

let a = 0
let b = 'hello'
let c = true
let d = null
let e = undefined
let f = {}
let g = []
let h = function(){}

console.log('a: ' + typeof a)
console.log('b: ' + typeof b)
console.log('c: ' + typeof c)
console.log('d: ' + typeof d)
console.log('e: ' + typeof e)
console.log('f: ' + typeof f)
console.log('g: ' + typeof g)
console.log('h: ' + typeof h)

/*
 * 执行结果:
 * a: number
 * b: string
 * c: boolean
 * d: object
 * e: undefined
 * f: object
 * g: object
 * h: function
**/

(2)Object.prototype.toString.call()

For detecting the type of a variable, you can solve the problem can not be detected typeof null and array of

let a = 0
let b = 'hello'
let c = true
let d = null
let e = undefined
let f = {}
let g = []
let h = function(){}

function typeOf(value) {
    return Object.prototype.toString.call(value).slice(8, -1)
}

console.log('a: ' + typeOf(a))
console.log('b: ' + typeOf(b))
console.log('c: ' + typeOf(c))
console.log('d: ' + typeOf(d))
console.log('e: ' + typeOf(e))
console.log('f: ' + typeOf(f))
console.log('g: ' + typeOf(g))
console.log('h: ' + typeOf(h))

/*
 * 执行结果:
 * a: Number
 * b: String
 * c: Boolean
 * d: Null
 * e: Undefined
 * f: Object
 * g: Array
 * h: Function
**/

(3)instanceof

Used to determine if an instance belongs to a certain type, you can solve typeof can not accurately determine the object type of problem

Instanceof determines the principle is the constructor prototype property right exists in the left object prototype chain

var Message = function(descrition) { // 构造函数
    this.detail = descrition
}

let message = new Message('Hello')
let object = new Object()

console.log(message instanceof Message)
console.log(message instanceof Object)
console.log(object instanceof Message)
console.log(object instanceof Object)
console.log(Message instanceof Object)

/*
 * 执行结果:
 * true
 * true
 * false
 * true
 * true
**/

3, type conversion

(1) cast

① String -> Number:parseInt(string[, radix]) & parseFloat(string)

parseIntFor string parsing an integer, the base can be specified; parseFloatfor resolving string to float

Both roughly the same principle, are parsed from the beginning of the first non-space character, until the end of the string or encounter an invalid numeric character

If successfully resolved, the return of figures; if the first non-space character is not a number or symbol, NaN is returned

let a = parseInt('   123abc')
let b = parseFloat(' 123.456abc')

console.log(a)
console.log(b)

/*
 * 执行结果:
 * 123
 * 123.456
**/

② Any -> Number:Number()

Conversion rules are as follows:

value Conversion rules
Number Direct output
String If the string is empty, then converted to 0
if string contains a valid integer format, converted to a decimal number
if the string contains a valid floating-point format, is converted into a floating-point number
if the string contains a valid ten hex format, then converted to hexadecimal number of
the remaining cases, converted to NaN
Boolean If true, it is converted into 1
if it is false, 0 is converted into
Null Converted into 0
Undefined Converted into 0
Object Object of the calling valueOf()method, according to the above rule conversion
if it is NaN, the Object calling toString()method, according to the above rule conversion
let a = Number(123)
let b = Number('456')
let c = Number(true)
let d = Number(false)
let e = Number(null)
let f = Number(undefined)
let g = Number(new Date())
let h = Number(new Array())

console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)
console.log(f)
console.log(g)
console.log(h)

/*
 * 执行结果:
 * 123
 * 456
 * 1
 * 0
 * 0
 * NaN
 * 1578556849729
 * 0
**/

③ Any -> String:String()

Conversion rules are as follows:

value Conversion rules
Number Converted into a digital value
String Direct output
Boolean If true, converted to true
if it is false, false converted into
Null Convert null
Undefined Convert undefined
Object Conversion according to specific rules
let a = String(123)
let b = String('asdf')
let c = String(true)
let d = String(false)
let e = String(null)
let f = String(undefined)
let g = String({})
let h = String([123, 'asdf', true, false, null, undefined])

console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)
console.log(f)
console.log(g)
console.log(h)

/*
 * 执行结果:
 * 123
 * asdf
 * true
 * false
 * null
 * undefined
 * [object Object]
 * 123,asdf,true,false,,
**/

(2) automatic conversion

Analyzing conditions ①

During determination condition, the value of the variable will be automatically converted to a Boolean value in accordance with the rules, the rules of conversion as follows:

value Conversion rules
Number 0, NaN false converted into
other cases converted to true
String False empty string converted into
the remaining cases converted to true
Null Converted into false
Undefined Converted into false
Object Converted to true
let a = 123
let b = ''
let c = null
let d = undefined
let e = {}

a ? console.log('true') : console.log('false')
b ? console.log('true') : console.log('false')
c ? console.log('true') : console.log('false')
d ? console.log('true') : console.log('false')
e ? console.log('true') : console.log('false')

/*
 * 执行结果:
 * true
 * false
 * false
 * false
 * true
**/

② numerical operations

  • For the +operator, the conversion rule is as follows:

    If the operand is not a string or object, by Number()converting into Number Type Function

    If there is an object or string operands, through String()converted into String type of the function

let a = 1 + true
let b = 1 + null
let c = 1 + undefined

let d = '1' + true
let e = '1' + null
let f = '1' + undefined

let g = '1' + 1
let h = {} + true
let i = [] + false

console.log(a)
console.log(b)
console.log(c)

console.log(d)
console.log(e)
console.log(f)

console.log(g)
console.log(h)
console.log(i)

/*
 * 执行结果:
 * 2
 * 1
 * NaN
 * 1true
 * 1null
 * 1undefined
 * 11
 * [object Object]true
 * false
**/
  • For -, *, /, %operator, through both the first Number()function into numerical calculation then

Implicit conversion rule based on numerical computation, we can easily obtain a shortcut number string interconversion

// number -> string
let number = 123
let string = number + ''
console.log(typeof string)
console.log(string)

/*
 * 执行结果:
 * string
 * 123
**/
// string -> number
let string = '123'
let number = string - 0
console.log(typeof number)
console.log(number)

/*
 * 执行结果:
 * number
 * 123
**/

③ equality operators

In use ==when the operator to compare the two variables are equal, if different types of variables, will then first comparison implicit conversion rules are as follows:

order Variable 1 Variable 2 operating
1 NaN * Return false
2 Null Undefined Returns true
3 Null Null Returns true
4 Undefined Undefined Returns true
5 Null In addition to Null, Undefined outside Return false
6 Undefined In addition to Null, Undefined outside Return false
7 Boolean * After converted into Boolean Comparison Number
8 Object Object When two objects point to the same memory address, will be equal
9 Object Number、String After Object converted into the original value (Number / String) comparing
the first to use valueOf()a method
if the object can be converted to the original value, the result is returned
otherwise the toString()method
if the object can be converted to the original value, then the results are returned
or thrown TypeErrorexception
10 Number Number Direct comparison
11 String String Direct comparison
12 String Number When you convert a String to compare Number

Practice a few topics:

false == 0   // true
false == '0' // true
false == []  // true
false == {}  // false
123 == [123] // true
2 == { valueOf(){ return 2 }} // true
1 == { valueOf: function(){ return [] }, toString: function(){ return 1 }} // true

The use ==time will be determined implicit conversion, it is generally used in the project===

4, assignment, shallow vs. deep copy

For basic types, assignment, deep and shallow copy copy all the old values of variables copied to a new variable, independently of each other between the old and new variable

let number = 159
let string = 'hello'

let number_copy = number
let string_copy = string

number_copy = 258
string_copy = 'hi'

console.log('number: ' + number) // 原变量的值不会改变
console.log('string: ' + string) // 原变量的值不会改变
console.log('number_copy: ' + number_copy)
console.log('string_copy: ' + string_copy)

/*
 * 执行结果:
 * number: 159
 * string: hello
 * number_copy: 258
 * string_copy: hi
**/

For reference types:

  • 赋值后新旧变量指向同一个内存地址,此时改变新变量会影响旧变量的值
let object = { first_name: 'Steve', last_name: 'Jobs' }
let array = [1, 3, 5]

let object_copy = object
let array_copy = array

object_copy['first_name'] = 'Steven'
array_copy[0] = 2

console.log('object["first_name"]: ' + object['first_name']) // 原变量的值发生改变
console.log('array[0]: ' + array[0]) // 原变量的值发生改变
console.log('object_copy["first_name"]: ' + object_copy['first_name'])
console.log('array_copy[0]: ' + array_copy[0])

/*
 * 执行结果:
 * object["first_name"]: Steven
 * array[0]: 2
 * object_copy["first_name"]: Steven
 * array_copy[0]: 2
**/
  • 浅拷贝得到的新变量,是将旧变量的第一层数据 赋值 给新变量
// 对于对象,常用的浅拷贝方式有:Object.assign
// 对于数组,常用的浅拷贝方式有:Array.from、slice、concat

let object = {
    name: {
        first_name: 'Steve',
        last_name: 'Jobs'
    },
    age: 18
}
let array = [[1, 3], 5, 7]

let object_shallow_copy = Object.assign({}, object)
let array_shallow_copy = Array.from(array)

object_shallow_copy['name']['first_name'] = 'Steven'
object_shallow_copy['age'] = 20
array_shallow_copy[0][0] = 2
array_shallow_copy[2] = 11

console.log('object["name"]["first_name"]: ' + object['name']['first_name'])
console.log('object["age"]: ' + object['age'])
console.log('array[0][0]: ' + array[0][0])
console.log('array[2]: ' + array[2])

console.log('object_shallow_copy["name"]["first_name"]: ' + object_shallow_copy['name']['first_name'])
console.log('object_shallow_copy["age"]: ' + object_shallow_copy['age'])
console.log('array_shallow_copy[0][0]: ' + array_shallow_copy[0][0])
console.log('array_shallow_copy[2]: ' + array_shallow_copy[2])

/*
 * 执行结果:
 * object["name"]["first_name"]: Steven
 * object["age"]: 18
 * array[0][0]: 2
 * array[2]: 7
 * object_shallow_copy["name"]["first_name"]: Steven
 * object_shallow_copy["age"]: 20
 * array_shallow_copy[0][0]: 2
 * array_shallow_copy[2]: 11
**/

自己来实现一个浅拷贝函数:

function shallowCopy(object) {
    if (typeof object !== 'object') return
    let newObject = object instanceof Array ? [] : {}
    for (let key in object) {
        if (object.hasOwnProperty(key)) {
            newObject[key] = object[key]
        }
    }
    return newObject
}
  • 深拷贝得到的新变量,是将旧变量的所有数据(无论嵌套多深)都 复制 给新变量,新旧变量之间互不影响
// 最简单的方法就是 JSON.parse(JSON.stringify())
let object = {
    name: {
        first_name: 'Steve',
        last_name: 'Jobs'
    },
    age: 18
}
let array = [[1, 3], 5, 7]

let object_deep_copy = JSON.parse(JSON.stringify(object))
let array_deep_copy = JSON.parse(JSON.stringify(array))

object_deep_copy['name']['first_name'] = 'Steven'
object_deep_copy['age'] = 20
array_deep_copy[0][0] = 2
array_deep_copy[2] = 11

console.log('object["name"]["first_name"]: ' + object['name']['first_name'])
console.log('object["age"]: ' + object['age'])
console.log('array[0][0]: ' + array[0][0])
console.log('array[2]: ' + array[2])

console.log('object_deep_copy["name"]["first_name"]: ' + object_deep_copy['name']['first_name'])
console.log('object_deep_copy["age"]: ' + object_deep_copy['age'])
console.log('array_deep_copy[0][0]: ' + array_deep_copy[0][0])
console.log('array_deep_copy[2]: ' + array_deep_copy[2])

/*
 * 执行结果:
 * object["name"]["first_name"]: Steve
 * object["age"]: 18
 * array[0][0]: 1
 * array[2]: 7
 * object_deep_copy["name"]["first_name"]: Steven
 * object_deep_copy["age"]: 20
 * array_deep_copy[0][0]: 2
 * array_deep_copy[2]: 11
**/

自己来实现一个深拷贝函数:

function deepCopy(object) {
    if (typeof object !== 'object') return
    let newObject = object instanceof Array ? [] : {}
    for (let key in object) {
        if (object.hasOwnProperty(key)) {
            let item = object[key]
            newObject[key] = typeof item === 'object' ? deepCopy(item) : item
        }
    }
    return newObject
}

【 阅读更多 JavaScript 系列文章,请看 JavaScript学习笔记

Guess you like

Origin www.cnblogs.com/wsmrzx/p/12175121.html