• 类型和语法


    函数不仅是对象,还可以拥有属性。函数对象的length属性是其声明的参数的个数。

    JavaScript中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。

    在对变量执行typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类型,因为JavaScript中的变量没有类型。

    变量在未持有值的时候为undefined,还没有在作用域中声明过的变量时undeclared。(is undefined 和 is not defined是两码事)

    使用delete运算符可以将单元从数组中删除。单元删除后数组的length属性并不会发生变化。

    数组通过数字进行索引,但也可以包含字符串键值和属性(这些并不计算在数组长度内)。

    如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当做数字索引来处理。

    字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。而数组的成员函数都是在其原始值上进行操作。(这也并不意味着所有的数组api都会改变原数组,不要误解。)

    toFixed方法不仅适用于数字变量,也适用于数字字面量。不过对于.运算符需要给予特别注意,因为它是一个有效的数字字符,会被优先识别为数字字面量的一部分,然后才是对象属性访问运算符。

    整数检测&安全的整数

    if(Number.isInteger){
        Number.isInteger = function(num){
            return typeof num === 'number' && num % 1 == 0
        }
    }
    
    if(Number.isSafeInteger){
        Number.isSafeInteger = function(num){
            return Number.isInteger(num) && Math.abs(num) <= Number.MAX_SAFE_INTEGER
        }
    }
    

    isNaN(...)有一个严重的缺陷,它的检查方式过于死板,就是“检查参数是否不是NaN,也不是数字”。

    NaN是JavaScript中唯一一个不等于自身的值。

    if(!Number.isNaN){
        Number.isNaN = function(n){
            return n !== n
        }
    }
    

    计算结果一旦溢出为无穷数(infinity)就无法再得到有穷数。换句话说,就是你可以从有穷数走向无穷,但无法从无穷回到有穷。

    验证-0(区分0与-0)

    function isNegZero(n){
        n = Number(n)
        return n === 0 && 1 / n === -Infinity
    }
    

    Object.is(...)来判断两个值是否绝对相等  

    if(!Object.is){
        Object.is = function(v1,v2){
            if(v1 === 0 && v2 === 0){
                return 1 / v1 === 1 / v2
            }
            if(v1 !== v1){
                return v2 !== v2
            }
            return v1 === v2
        }
    }
    

    参数值总是通过值复制的方式传递,即便对复杂的对象值也是如此。

    简单值总是通过值复制的方式来赋值或传递;复合值总是通过引用复制的方法来赋值或传递。

    典型面试题

    let array = [1,2,3]
    function foo(arr){
        arr.push(4)
        arr = [5,6,7]
        console.log(arr)//[5,6,7]
    }
    foo(array)
    console.log(array)//[1,2,3,4]
    

    我们无法自行决定使用值复制还是引用复制,一切由值的类型来决定。

    一般情况下,我们不需要直接使用封装对象,最好是让JavaScript引擎自己决定什么时候应该使用封装对象。因为浏览器已经为这样的常见情况作了性能优化,直接使用封装对象来“提前优化”代码反而会降低执行效率。

    如果想要自行封装基本类型值,可以使用Object(...)函数(不带new关键字)。

    我们将包含至少一个“空单元”的数组称为“稀疏数组”。

    Function.prototype是一个函数;RegExp.prototype是一个正则表达式;Array.prototype是一个数组。

    将值从一种类型转换为另一种类型通常称为类型转换。

    JavaScript中的强制类型转换总是返回标量基本类型值。

    类型转换发生在静态类型语言的编译阶段,而强制类型转换则发生在动态类型语言的运行时(runtime)。

    var a = 1;
    var b = a + '';//隐式强制类型转换
    var c = String(a);//显式强制类型转换

    抽象操作ToString,负责处理非字符串到字符串的强制类型转换。

    对普通对象来说,除非自定义,否则toString()(Object.prototype.toString())返回内部属性[[class]]的值。

    如果对象有自己的toString()方法,字符串化时就会调用该方法并使用其返回值。

    数组的默认toString()方法经过了重新定义,将所有单元字符串化后再用“,”连接起来。

    所有安全的JSON值(JSON-safe)都可以使用JSON.stringify(...)字符串化。安全的JSON值是指能够呈现为有效JSON格式的值。

    不安全的JSON值:undefined、function、symbol和包含循环引用的对象都不符合JSON结构标准,支持JSON的语言无法处理它们。

    JSON.stringify(...)在对象中遇到undefined、function、symbol时会自动将其忽略,在数组中则会返回null(以保证单元位置不变)。

    如果对象中定义了toJSON()方法,JSON字符串化时就会首先调用该方法,然后用它的返回值来进行序列化。

    如果要对含有非法JSON值的对象进行字符串化,或者对象中某些值无法被序列化时,就需要定义toJSON()方法来返回一个安全的JSON值。

    toJSON()返回的应该是一个适当的值,可以是任何类型,然后再由JSON.stringify()对其进行字符串化。也就是说,toJSON()应该返回一个能够被字符串化的安全的JSON值,而不是返回一个JSON字符串。

    我们可以向JSON.stringify(...)传递一个可选参数replacer,它可以是数组或是函数,用来指定对象序列化过程中哪些属性应该被处理,哪些应该被排除。如果replacer是一个数组,那么它会对对象本身调用一次,然后对对象中的每个属性各调用一次,每次传递两个参数,键和值。如果要忽略某个键就返回undefined,否则返回指定的值。

    JSON.stringify(...)还有一个可选参数space,用来指定缩进格式。

    • 字符串、数字、布尔值和null的JSON.stringify(...)规则与toString基本相同。
    • 如果传递给JSON.stringify(...)的对象中定义了toJSON()方法,那么该方法会在字符串化前调用,以便将对象转换为安全的JSON值。

    JavaScript中的值可以分为两类:

    • 可以被强制类型转换为false的值
    • 其他(被强制类型转换为true的值)

    假值

    • undefined
    • null
    • false
    • +0、-0、NaN
    • ""

    假值的布尔强制类型转换结果为false。

    解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否则会失败并返回NaN。

    一元运算符 ! 显示地将值强制类型转换为布尔值,但是它同时还将真值反转为假值(或者将假值转为真值)。所以显示强制类型转换为布尔值最常用的方法是 !!,因为第二个 ! 会将结果反转回原值。 

    ES6允许符号到字符串的显示强制类型转换 ,然而隐式强制类型转换会产生错误,符号不能够被强制类型转换为数字(显式和隐式都会产生错误),但可以被强制类型转换为布尔值(显式和隐式结果都是true)。

    常见误区:==检查值是否相等;===检查值和类型是否相等;

    正确解释:==允许在相等比较中进行强制类型转换,而===不允许。

    • 如果Type(x)是数字,Type(y)是字符串,则返回x == ToNumber(y)的结果。
    • 如果Type(x)是字符串,Type(y)是数字,则返回ToNumber(x) == y的结果。
    • 如果Type(x)是布尔类型,则返回ToNumber(x) == y的结果。
    • 如果Type(y)是布尔类型,则返回x == toNumber(y)的结果。

    了解超过一个运算符是表达式的执行顺序,这些规则被称为“运算符优先级”。

    &&运算符优先于||执行,而且执行顺序并非我们所设想的从左到右。 而||的优先级又高于? : 。

    如果运算符优先级/关联规则能够令代码更简洁就是用运算符优先级/关联规则;如果( )有助于提高代码可读性,就是用( )。

    finally中的代码总会在try之后执行,如果有catch的话则在catch之后执行。也可以将finally中的代码看做一个回调函数,即无论出现什么情况最后一定会被调用。

    在函数中省略return的结果和return;即return undefined;是一样的,但是在finally中省略return则会返回前面的return设定的返回值。

    case表达式的匹配算法与===相同。

  • 相关阅读:
    Unity异步加载场景loading条
    (转)Unity3D命令行Build
    (转)Unity3d UnityEditor编辑器定制和开发插件
    (转)U3D不同平台载入XML文件的方法——IOS MAC Android
    Unity3D中的欧拉角的理解
    (转)在ios android设备上使用 Protobuf (使用dll方式)
    (转)[原创]在ios android设备上使用 Protobuf (使用源码方式)
    (转)欧拉角与万向节死锁
    (转) unity 在移动平台中,文件操作路径详解
    微信小程序四(设置底部导航)
  • 原文地址:https://www.cnblogs.com/zhenjianyu/p/13276339.html
Copyright © 2020-2023  润新知