zoukankan      html  css  js  c++  java
  • 侯策《前端开发核心知识进阶》读书笔记——JS基础

    JavaScript 类型及其判断

    JavaScript 具有七种内置数据类型,它们分别是:null、undefined、boolean、number、string、object、symbol,其中object 类型又具体包含了 function、array、date 等

    对于这些类型的判断,我们常用的方法有:typeof、instanceof、Object.prototype.toString、constructor

    (一)typeof

    使用 typeof 可以准确判断出除 null 以外的基本类型,以及 function 类型、symbol 类型;null 会被 typeof 判断为 object。

    typeof 5 // "number"
    typeof 'lucas' // "string"
    typeof undefined // "undefined"
    typeof true // "boolean"
    typeof null // "object"
    const foo = () => 1
    typeof foo // "function"
    const foo = {}
    typeof foo // "object"
    const foo = []
    typeof foo // "object"
    const foo = new Date()
    typeof foo // "object"
    const foo = Symbol("foo") 
    typeof foo // "symbol"

    (二)instanceof 

    使用 a instanceof B 判断的是:a 是否为 B 的实例,即 a 的原型链上是否存在 B 构造函数。

    function Person(name) {
        this.name = name
    }
    const p = new Person('lucas')
    
    p instanceof Person
    // true

    (三) Object.prototype.toString 

    console.log(Object.prototype.toString.call(1)) 
    // [object Number]
    
    console.log(Object.prototype.toString.call('lucas')) 
    // [object String]
    
    console.log(Object.prototype.toString.call(undefined)) 
    // [object Undefined]
    
    console.log(Object.prototype.toString.call(true)) 
    // [object Boolean]
    
    console.log(Object.prototype.toString.call({})) 
    // [object Object]
    
    console.log(Object.prototype.toString.call([])) 
    // [object Array]
    
    console.log(Object.prototype.toString.call(function(){})) 
    // [object Function]
    
    console.log(Object.prototype.toString.call(null)) 
    // [object Null]
    
    console.log(Object.prototype.toString.call(Symbol('lucas'))) 
    // [object Symbol]

    (四)constructor 

    var foo = 5
    foo.constructor
    // ƒ Number() { [native code] }
    
    var foo = 'Lucas'
    foo.constructor
    // ƒ String() { [native code] }
    
    var foo = true
    foo.constructor
    // ƒ Boolean() { [native code] }
    
    var foo = []
    foo.constructor
    // ƒ Array() { [native code] }
    
    var foo = {}
    foo.constructor
    // ƒ Object() { [native code] }
    
    var foo = () => 1
    foo.constructor
    // ƒ Function() { [native code] }
    
    var foo = new Date()
    foo.constructor
    // ƒ Date() { [native code] }
    
    var foo = Symbol("foo") 
    foo.constructor
    // ƒ Symbol() { [native code] }
    
    var foo = undefined
    foo.constructor
    // VM257:1 Uncaught TypeError: Cannot read property 'constructor' of undefined
        at <anonymous>:1:5
    
    var foo = null
    foo.constructor
    // VM334:1 Uncaught TypeError: Cannot read property 'constructor' of null
        at <anonymous>:1:5

    对于 undefined 和 null,如果尝试读取其 constructor 属性,将会进行报错。并且 constructor 返回的是构造函数本身,一般使用它来判断类型的情况并不多见。

    JavaScript 类型及其转换

    JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。

    console.log(1 + '1')
    // 11
    
    console.log(1 + true)
    // 2
    
    console.log(1 + false)
    // 1
    
    console.log(1 + undefined)
    // NaN
    
    console.log('lucas' + true)
    // lucastrue

    当使用 + 运算符计算 string 和其他类型相加时,都会转换为 string 类型;其他情况,都会转换为 number 类型,但是 undefined 会转换为 NaN,相加结果也是 NaN

    当使用 + 运算符计算时,如果存在复杂类型,那么复杂类型将会转换为基本类型,再进行运算

    对象在转换基本类型时,会调用该对象上 valueOf 或 toString 这两个方法,该方法的返回值是转换为基本类型的结果

    JS中Number()、parseInt()和parseFloat()  

    JS中的NAN 

    JavaScript 函数参数传递

    let foo = 1
    const bar = value => {
        value = 2
        console.log(value)
    }
    bar(foo)
    console.log(foo) 
    //2 1
    let foo = {bar: 1}
    const func = obj => {
        obj.bar = 2
        console.log(obj.bar)
    }
    func(foo)
    console.log(foo)
    //2 {bar: 2}

    数为基本类型时,函数体内复制了一份参数值,而不会影响参数实际值。如果函数参数是一个引用类型,当在函数体内修改这个引用类型参数的某个属性值时,将会对参数进行修改。因为这时候函数体内的引用地址指向了原来的参数。

    cannot read property of undefined 问题解决方案

    const obj = {
        user: {
            posts: [
                { title: 'Foo', comments: [ 'Good one!', 'Interesting...' ] },
                { title: 'Bar', comments: [ 'Ok' ] },
                { title: 'Baz', comments: []}
            ],
            comments: []
        }
    }

    验证对象每一个 key 的存在性。常见的处理方案:

    && 短路运算符进行可访问性嗅探

    obj.user &&
    obj.user.posts &&
    obj.user.posts[0] &&
    obj.user.posts[0].comments

    || 单元设置默认保底值

    (((obj.user || {}).posts||{})[0]||{}).comments 

    try…catch

    var result
    try {
        result = obj.user.posts[0].comments
    }
    catch {
        result = null
    }

    例题:

    Can (a == 1 && a == 2 && a == 3) ever evaluate to true?

    const a = {
        value: 1,
        toString: function () {
            return a.value++
        }
    }
    console.log(a == 1 && a == 2 && a == 3) // true
    
    let value = 0
    Object.defineProperty(window, 'a', {
        get: function() {
            return ++value
        }
    })
    
    console.log(a == 1 && a == 2 && a == 3) // true
  • 相关阅读:
    网络编程学习小结
    我的学习笔记_Windows_HOOK编程 2009-12-03 11:19
    void及void指针含义的深刻解析
    Android开发之自己定义TabHost文字及背景(源码分享)
    ActionBar自己定义改动无效解决方法
    一位Erlang程序猿的自白
    Xcode 5.1安装插件:规范凝视生成器VVDocumenter
    Socket程序中的Error#10054错误
    CSDN博客清理缓存
    ACM 位运算
  • 原文地址:https://www.cnblogs.com/fmyao/p/12802090.html
Copyright © 2011-2022 走看看