JavaScript高级程序设计

JavaScript高级程序设计,第1张

 参考 B站up主猿油站

1 语言基础

大小写:ECMAScript 中的一切都是区分大小写的,无论是变量 *** 作符还是函数名。

标识符:是变量函数或函数参数的名称,标识符规则:

首字母必须是 字母 _ $ 剩余的字符可以是字母,数字。下划线,美元符号。标识符中的字母可以是ASCII特殊字符(不推荐)标识符(推荐)使用驼峰命名关键字,保留字无法使用 1.1 变量 ECMAScript 变量是松散类型,变量可以保存 “任何数据类型”每个变量只是用于保存任意值的命名占位符,声明变量三个关键字:var,let,const

var 声明:

var 声明的范围是函数作用域全局使用 var 声明的变量会自动成为 window的属性,而 let const 不会
foo();      // 2. "my is foo"
console.log(name);   // 4. 李四

function foo() {
    console.log(age);   // 1. undefined      变量会自动提升到函数作用域顶部;   
    var age = 18;
    var age = 20
    name = "李四"       // 省略 var  *** 作符,会创建一个全局变量(不推荐)
    console.log("my is foo");
    console.log(age);  // 3. 20
}

 let 声明:

作用域:

let 声明的范围是块作用域;if语句属于块作用域;作用域仅限于该块内部。块作用域是函数作用域的子集,因此适用于 var 的作用域限制同样也适用于 let 。let 声明的变量不会在作用域中被提升。let不允许同一块作用域中出现相同声明; let 声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛ReferenceError 。
{
// age 不会被提升
console.log(age); // ReferenceError:age 没有定义
let age = 26;

//对声明冗余报错不会因混用 let 和 var 而受影响。
//这两个关键字声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在。
var name;
let name; // SyntaxError
let age;
var age; // SyntaxError
}

 const 声明:

const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。(类似常量)const 不允许修改值的引用地址,如果变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制。
const age = 26;
age = 36; // TypeError: 给常量赋值

// const 也不允许重复声明
const name = 'Matt';
const name = 'Nicholas'; // SyntaxError
// const 声明的作用域也是块
const name = 'Matt';
if (true) {
const name = 'Nicholas';
}
console.log(name); // Matt

2 数据类型及转换 简单数据类型(非引用数据类型)数据值直接存储到内存空间: Undefiend,Null,Boolean,Number,String ,Symbol (值保存在栈中,按值访问;)复杂数据类型(引用类型):Object(存放在堆中,存的是地址,地址指向) array类型 也是object的子集typof *** 作符不是一个函数,但可以像函数一样传参调用;返回值是 *** 作值类型数据的字符串表示
let message = "some string";
console.log(typeof message); // "string"


function foo () {

}
// var fn = foo()      // 赋值,指向的是 函数的返回值
// fn();

console.log(typeof null);  //object    null实际上是一个空对象的引用
console.log(typeof foo()); //function  函数本身是object类型 因为函数的特殊性返回 ‘function’
console.log(typeof undefined);   //undefined  

let name 
console.log(typeof name);       //undefined    默认情况下所有已声明未初始化的变量都会赋值为undefined

2.1 Undefined类型:

        是一个假值,例如 ’ '  null 也都是假值

2.2 ​​​​​​​Null类型

        null类型只有一个null值,表示空对象指针。

        声明一个要保存值的 对象类型 时,推荐使用 null 来初始化

console.log(null == undefined);  // true

// String 类型     非空字符串为‘true’  空字符串为‘false’
// Number 类型     非0 为‘true’     ‘0’ 或 ‘NaN’ 为false
// Object 类型     任意对象均为‘true’    'null'控制针对象为false
// Undefined 类型    所以undefined都为false

console.log(NaN == NaN);  //false   1.对其后续任意运算均返回 NaN 2.不等于任何值包括本身

// 3.判断是否是NaN需要调用  isNaN() 函数判断
let num = NaN
let num2 = 222
console.log(typeof num);
console.log(isNaN(num));  //true
console.log(isNaN(num2));  //false

2.3 String类型:

        JS中是String 类型表示 Unicode 的字符序列,双引号、单引号、反引号表示。

        String()可以将null,undefined转化为字符串,而toString()不可以

        解释: null和undefined作为一种单独的数据类型,它们没有继承Object.prototype,因此不存在toString()方法,所以转换不了字符串;而String()这个是全局方法,是都可以获取的

const num = 123;
const foo = null
console.log(num.toString()); //123
// console.log(foo.toString());    //Cannot read property 'toString' of null
console.log(String(null));
console.log(String(num));   

es6模板字符串:严格意义来讲并不是字符串,而是一个特殊的JavaScript表达式,返回值为一个字符串。并且在定义时立即执行,转化为字符串实例。   `模板字符串 ${}`

const name = '张三'
console.log(`他叫${name}`); //他叫张三    模板字符串 计算插值内的表达式的值

2.4 Boole​​​​​​​an类型:
/*  显示布尔值转换
        构造函数 Boolean()
        两个逻辑非 !!() 符号,隐式转换
            所有表示没有的或0都为false,有或者1的为true.
            特殊的: {} 空对象为true
*/
console.log(Boolean(undefined));    //false
console.log(Boolean(null));     //false
console.log(Boolean(0));        //false
console.log(Boolean(''));   //false
console.log(Boolean([]));   //true 数组属于对象
console.log(Boolean({}));   //true,真正的空对象用 null 来表示

2.5 Number() 类型​​​​​​​

        JS数字类型只有number类型,number类型相当于其它强类型语言中的dobule类型(双精度浮点型),不区分浮点型和整数型。

        number有四种进制表示方法:二进制、十进制、八进制、十六进制

/* 
    1. 布尔值类型 true转1  false转0
    2. 数值类型,直接返回
    3. 字符串类型,空字符串返回 0, 
        非空字符串内容是数值转换为数字且忽略无效前缀,
        其它返回 NaN
    4. 对象类型 null返回0 非空数组调用valueOf方法,返回值继续安装number()规则转换
*/

console.log(Number('a'));   // NaN
console.log(Number(''));    // 0
console.log(Number('123'));    // 123
console.log(Number('000011'));  // 11
console.log(Number(true));  // 1
const obj = {}
console.log(Number(obj));   //NaN
const arr = ['1', '2']
console.log(Number(arr).valueOf);   // [Function: valueOf] 



// 第一个参数必须, 数字类型和字符串类型,其它类型为NaN 第二个参数  2-36进制可选
console.log(parseInt('1232', 10));  //1232
console.log(parseInt('1232', 1));  //NaN    1进制z
console.log(parseInt('1232ABC'));  //1232  字符不正确停止截取
console.log(parseInt('ABC1232'));  //NaN  首字符不正确NaN
console.log(parseInt('0xf'));  //15


// parseFloat() 从第一个非空字符串开始转换,解析到末尾或者第一个无效的浮点数字符为止。
// 所以十六进制都返回0 (没法表示小数)
console.log(parseFloat('12.11aaa'));  //12.11
console.log(parseFloat('.11aaa'));  //0.11
console.log(parseFloat('0xf'));  //0

2.6 Symbol类型:

        ES6新增类型,用来创建唯一记号的符号类型。

        symbol(描述),每个创建的symbol都不等于上一个,即使相同的描述。

        不支持new关键字创建,防止传入初始化对象产生歧义。

        symbol可以通过 symbol.for(key) 函数传入参数可以共用同一个符号

2.7 Undefined和Null区别: 他们都是简单数据类型;转化为布尔值都为 false ,转化为数字类型时, undefined为 NaN;Null 为 0Null是空指针对象(一般用于赋予对象空的初始值),Undefined 是所有已声明未初始化的默认值Undefined不是JS保留关键字,但Null 是;

2.8 小数运算精度问题

精度计算:

        计算机是二进制运算的,十进制会被转换为二进制。 二进制小数位部分数会无限循环,计算机可支持浮点数小数部分只到52位,所以导致小数位精度不准。

console.log(0.1 + 0.1 == 0.2);  //true
console.log(0.1 + 0.2 == 0.3);  // false

    // 加法
    0.1 + 0.2 = 0.30000000000000004
    0.7 + 0.1 = 0.7999999999999999
    0.2 + 0.4 = 0.6000000000000001

    // 减法
    1.5 - 1.2 = 0.30000000000000004
    0.3 - 0.2 = 0.09999999999999998
    
    // 乘法
    19.9 * 100 = 1989.9999999999998
    0.8 * 3 = 2.4000000000000004
    35.41 * 100 = 3540.9999999999995

    // 除法
    0.3 / 0.1 = 2.9999999999999996
    0.69 / 10 = 0.06899999999999999

作者:LPieces
链接:https://juejin.cn/post/6980282248104771615
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

解决办法:

// 方式一: 小数因为无限循环导致精度丢失,通过改函数限制小数位数 (精度一般出现在最末尾)
console.log(139.605.toFixed(2));        // 139.60    四舍五入为指定小数位数的数字


// 方式二:
//    因为整数不会出现丢失,将小数部分 0.1 * 10,运算结束后在  除10转换为小数。

计算精度问题推荐使用第三方库:Math.js  big.js

 2.9 typeof 类型判断
const type =  typeof '中国万岁'; // string
typeof 666; // number
typeof true; // boolean
typeof undefined; // undefined
typeof Symbol(); // symbol
typeof 1n; // bigint
typeof () => {}; // function

typeof []; // object
typeof {}; // object
typeof new String('xxx'); // object

typeof null; // object

通过以上例子可以看出,typeof只能准确判断原始数据类型和函数(函数其实是对象,并不属于另一种数据类型,但也能够使用 typeof 进行区分),无法精确判断出引用数据类型(统统返回 object)。

有一点需要注意,调用typeof null返回的是object,这是因为特殊值null被认为是一个对空对象的引用(也叫空对象指针)。

如果想准确判断引用数据类型,可以用instanceof运算符。判断数组可以用ES6:Array.isArray(数组)

参考链接:typeof 和 instanceof 的区别

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1299050.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存