JavaScript易忽略点补漏

原生JS查疑补漏

1. 分号

  • 通常语句不添加;也可以正常运行,是因为JS默认将每一行的换行符理解为分号
  • 而有一些必须添加
alert("1");  //这里的;不可缺少,否则将理解为一行语句;
[1,2].forEach(alert);

2. 注释

  • 不支持注释嵌套

3. 严格模式/现代模式

  • “use strict” 将启用最新的规则
  • 必须放在脚本的最上面
  • classesmodules会默认使用该模式
  • 模式下变量必须先声明再使用

4. let

  • let声明的变量作用域在其声明语句之后。
  • 小心暂时性死区
  • 声明变量的时候会绑定所在控件,控件会清空同名全局变量的影响。

5. 数据类型

5.1 Number

  • 1/0=>Infinity
  • NaN=>一个不正确的表达式。
  • number类型区间-(253-1)~(253-1)
  • 超出使用bigInt,Safari/IE都不支持
//以n结尾
bigInt=121111111111111111111111111111111111111111111111n;

5.2 String

  • 可以使用反引号`
  • 使用反引号之后就可以直接进行变量/常量/表达式引用了
let str ="kelasi"
alert(`geyou say niubi${str}`); //"geyou say niubikelasi"

感觉就是把jQuery的东西直接拿来用了,应该是ES6的新东西把,要么就是我之前学的时候不仔细漏掉了 逃

5.3 symbol

??? 是ES6的新东西把? 学过之后填坑。

6 类型转换

6.1 转数字类型

  • +一元运算符
  • Nmuber()函数
    • undefined => NaN
    • null => 0
    • true/false => 1/0

6.2 转boolean

  • 非空为true 空为false
  • bool=Boolean("0") //bool = true

7 运算符

  • ==当两侧类型不同时先将两侧变量转化为数值型再进行比较。
"213"==true ; //false
"1" == true ; //true
  • 使用<、>、<=、>=时
    • null => 0
    • undefined => NaN
  • ===不会对两边进行类型转换。
  • &&||级别高
  • ??运算符:取元中第一个已定义的元。
    • ??禁止和&&、||一起使用。加括号分离后可用

8 switch

  • case和arg 的比较是使用===进行的

9 函数

函数命名

  • 通过对行为的描述
    • show…
    • get…
    • calc…
    • create…
    • check…
  • 不要再函数内进行多余的操作(createTable()就应当只创建Table而不是做多余的操作);

函数表达式&函数声明

//函数声明
function sum(a,b){
    return a+b;
}
//函数表达式
let sum =function(a,b){
    return a+b;
};

区别在于:函数创建的时间

10 测试

BDD行为驱动测试开发
    - 测试
    - 文档 告诉我们测试做了什么
    - 案例 作为案例来展示函数应该怎样使用

10.1 库

  • Mocha
<head>
    <script src = "https://cdnjs.cloudflare.come/ajax/libs/mocha/3.2.0/mocha.js"></script>
    <script>
        mocha.setup("bdd");
    </script>
</head>
<body>
    ...
    <div id = "mocha"></div>
    <script src = "test.js"></script>
    <script>
        mocha.run();
    </script>
</body>
  • Chai
<head>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
    <script>
        let assert=chai.assert;
    </script>
</head>

完整的断言列表见chaidoc

  • Sinon

10.2 描述文件

//test.js文件
describe("title",function(){
    it("描述部分",function(){
        //断言部分
        assert.equal(arg1,arg2);
    })
});
  • 可以通过嵌套describe来进行测试分组
  • before/after
  • beforeEach/afterEach

11 对象Object

11.1属性

声明
  • const不能重新赋值但可以修改
  • 对象属性常量方法见后

行属性调用

声明缩写
function makeUser(name,age){
    return{
        name:name,
        age:age,
        // 其他属性
    };
}
let user= makeUser("John",30);

当出现上面这种属性名和变量名一样,通过变量生成属性的场景,可以使用缩写

function makeUser(name,age){
    return{
        name,
        age,
        ...
    };
}

甚至 我们可以这样使用

let user={
    name,
    age:30,
};
使用
  • 推荐使用object[属性名]
属性的命名
  • 与变量名不同的是,属性名称使用保留字并不会报错。
  • 无论属性名使用的是什么,都会默认转换为字符串类型
  • __proto__该属性不能设置非对象的值
判断是否存在该属性
  • object.key===undefinedtrue不存在,false存在
  • "key" in objecttrue存在,false不存在
for in

属性名是整数?升序排列:创建顺序排列;

克隆合并

Object.assign(dest,[src1,src2...])

  • dest=>目标object
  • [src…]=>源对象列表
  • 用于克隆或合并对象
  • 存在的属性会被覆盖
  • **存在问题:**被克隆对象的子对象并未被克隆而是引用。
//使用深层克隆来解决子对象的引用问题
//方法1:
function deepClone(origin,target){
    var target =target || {};
    let toStr =Object.prototype.toString,
    arrStr="[object Array]";
    for (let prop in origin){
        if (origin[prop]!=null && typeof(origin[prop]))=="object"{
            target[prop] = (toStr.call(origin[prop])==arrStr)?[]:{};
            deepClone(origin[prop],target[prop]);
        }else{
            target[prop]=origin[prop];
        }
    }
}
//方法2:
//方法无法被拷贝过去。
obj2 =JSON.parse(JSON.stringify(obj1));

11.2 方法

user = {
    sayHi:function(){
        alert("hello");
    }
};
//简写
let user = {
    sayHi(){
        alert("hello");
    }
};
this
  • this的指向由上下文决定
  • 没有对象调用的情况下 this==undefined
  • 箭头函数内的this取决与外部。
链式调用

再方法中添加return this;完成链式调用

11.3 构造函数

new.target
  • new.target可以检测用户调用该函数时候是否使用了new

11.4 可选链"?."

  • 问题:如user.address.street,有些用户对象填写了address则可以调用,有些没有填写,则会报错。
  • 解决方案:
    • 再过去使用(user && user.address && user.address.street)确保不会报错,
    • 现在(user?.address?.street);
    • 解决方案只能保证不报错,如为空返回undefined。
  • 不要过度使用可选链接,只放在必要的地方 如user.address?.street
  • 可以用于删除,可以用于读取,不可以写入
  • ?.检测左侧对象或属性

12 垃圾回收

  • 不可达皆回收

13 Symbol

symbol类似与一种标记,如其名。

Symbol我的博客

14 对象的原始值转换

原始值就是基本数据类型的值

语法:
Symbol.toPrimitive(input,preferedType?);

步骤:

转Number=>

  1. 如果input是原始值,返回input;
  2. 如果input是对象,调用input.valueOf(),如果结果是原始值,则返回结果;
  3. 调用input.toString(),如果是原始值,返回结果;
  4. 抛出Error

转String=>

  1. 如果input是原始值,返回input;
  2. 如果input是对象,调用input.toString(),如果结果是原始值,则返回结果;
  3. 调用input.valueOf(),如果是原始值,返回结果;
  4. 抛出Error

默认情况下,日期会被认为转为字符串,其它转为Number;

[]+[]; //""
[]+{}; //[object object];
{}+[]; //0

如何判断是String还是Number呢?
->hint
只有三种hint:

  1. String
  2. Number
  3. default 二元不确定的时候

使用例子

//例1: 使用系统Symbol
let user ={
    name:"Wang",
    money:1000,

    [Symbol.toPrimitive](hint){
        alert(`hint:${hint}`);
        return hint == "string"? `{name:"${this.name}"}`:this.money;
    }
};

console.log(user);//hint:string ->{name:"Wang"}
console.log(+user);//hint:number -> 1000
console.log(user + 500); //hint:default ->1500
//例2: 不使用Symbol
let user ={
    name:"Wang",
    money:1000,

    toString(){
        return `{name:"${this.name}"}`;
    },
    valueOf(){
        return this.money;
    },
};

两个例子区别在于:使用Symbol.toPrimitive(hint)要求必须有返回值,使用toString()valueOf()没有返回值会忽略

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值