变量test和变量Test是不同的变量。typeof不能作为函数名(关键字),但Typeof合法
变量、函数、属性、函数参数的名称
ES3不规范的写法会被处理,对于不安全的活动将抛出错误
对整个脚本启用严格模式
"use strict";
单独一个函数在严格模式下执行
function doSomething(){ "use strict"; //函数体 }
js的变量是松散类型的,var、const和let都可以声明变量
var message;
如果声明的变量未初始化变量为undefined
function test(){ message = "hi"; } test(); console.log(message); //"hi"
var message = "hi", found = fales, age = 29;
console.log(age); //undefined var age = 26; //与下方代码等价 var age; console.log(age); var age = 26;
注:关于for循环
for循环中var的问题
// 迭代遍历渗透到循环体外部 for(var i=0; i<5; i++){ //循环体 } console.log(i); //5 //定时器问题 for(var i=0; i<5; i++){ setTimeout(()=>console.log(i),0); } //实际输出 5、5、5、5、5
如果使用let声明迭代变量,每次循环会成名一个新的迭代变量
const与let基本相同 唯一的区别时声明变量时必须初始化,且修改会报错
注:如果修改对象中的属性则不受限制
for-in 与 for-of使用 const
for(const key in {a:1, b:2}){ console.log(key); } // a,b //for-in为迭代对象的键 for(const value of [1,2,3,4,5]){ console.log(value); } // 1, 2, 3, 4, 5 //for-of迭代实现iterator的对象
ECMAScript有6种简单数据类型(也称为原始类 型):Undefined、Null、Boolean、Number、 String和Symbol。Symbol(符号)是 ECMAScript 6新增的。还有一种复杂数据类型叫 Object(对象)。
因为ECMAScript的类型系统是松散的,所以需要一 种手段来确定任意变量的数据类型。
console.log(typeof 95); // "number" console.log(typeof("message")); // "string"
注: typeof是一个操作符而不是函数,但可以使用参数。
变量声明未赋值,值为undefined
let message; // let message = undefined; 等价 console.log(message == undefined); // true
对未声明的变量使用typeof 也为 "undefined"
// 确保没有声明过这个变量 // let age console.log(typeof age); //"undefined"
在定义将来要保存对象值的变量时,建议使用null 来初始化
注:undefined值是由null值派生而来的,因此 ECMA-262将它们定义为表面上相等
console.log(null == undefined); //true
布尔值字面量true和false是区分大小写的
任何类型的值都可以调用Boolean()函数转化为Boolean类型
数值类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 非空字符串 | ""(空字符串) |
Number | 非零数值(包括无穷值) | 0、NaN |
Object | 任意对象 | null |
Undefined | N/A(不存在) | undefined |
注:像if等流控制语句会 自动执行其他类型值到布尔值的转换
浮点数
let floatNum1 = 0.1; let floatNum2 = .1; // 有效,但不推荐 let floatNum3 = 1.; // 小数点后面没有数字,当成整数1处理 let floatNum4 = 10.0; // 小数点后面是零,当成整数10处理 let floatNum5 = 3.125e7; // 等于31250000 let floatNum6 = 0.0000003; // 等于3e-7 //ECMAScript会将小数点后至少包含6个零的浮点值转换为科学记数法 let floatNum7 = 0.1+0.2; // 等于0.300000000000004 存在舍入错误
console.log(0/0); // NaN console.log(-0/+0); // NaN console.log(5/0); // Infinity console.log(5/-0); // - Infinity
任何涉及 NaN的操作始终返回NaN
console.log(NaN == NaN); //false // NaN与任何值不相等
ECMAScript提供了isNaN()函数,一个值传给isNaN()后,该函数会尝试把它转换为数值,任何不能转换为数值的值都会导致这个函数返回true。
类型 | 结果 |
---|---|
boolean | true转为1,false转为0 |
数值 | 直接返回 |
null | 0 |
undefined | NaN |
字符串 | 1. 完全符合数字格式返回该数字 2. 空字符串返回0 3. 其他情形返回NaN |
对象 | 先调用valueOf()然后按上述方法转换,如果为NaN 则再调用toString() 方法,再按上述方法转换 |
let num1 = parseInt("1234blue"); //1234 let num2 = parseInt("");// NaN let num3 = parseInt("0xA");// 10,解释为十六进制整数 let num4 = parseInt(22.5);// 22
第二个参数 代表进制
let num1 = parseInt("10", 2);// 2,按二进制解析 let num2 = parseInt("10", 8);// 8,按八进制解析 let num3 = parseInt("10",10); // 10,按十进制解析 let num4 = parseInt("AF",16); // 175 let num5 = parseInt("AF");// NaN
let num1 = parseFloat("1234blue"); //1234,按整数解析 let num2 = parseFloat("0xA");// 0 let num3 = parseFloat("22.5"); //22.5 let num4 = parseFloat("22.34.5"); //22.34
String(字符串)数据类型表示零或多个16位 Unicode字符序列。字符串可以使用双引号(")、 单引号(‘)或反引号(`)标示
\xnn | 以十六进制编码nn表示的字符 (其中n是十六进制数字 0~F), 例如\x41等于"A" |
\unnnn | 以十六进制编码nnnn表示的 Unicode字符(其中n是十六 进制数字0~F), 例如 \u03a3等于希腊字符"Σ" |
let num = 10; console.log(num.toString());// "10" console.log(num.toString(2));// "1010" console.log(num.toString(8));// "12" console.log(num.toString(10)); // "10" console.log(num.toString(16)); // "a"
值有toSring()方法 | 调用并返回结果 |
null | 返回 "null" |
undefined | "undefined" |
let value = 5; let exponent = ‘second‘; let interpolatedTemplateLiteral = `${ value } to the ${exponent } power is ${ value * value }`; console.log(interpolatedTemplateLiteral); // 5 to the second power is 25
插入的值都会使用toString()强制转型为字符串(实际使用的是String() 函数)
③字面量也支持特有的标签函数 以及String.raw可用于查看原始字面量内容 此处略
let sym = Symbol(); console.log(typeof sym); //symbol let fooSymbol = Symbol(‘foo‘); let otherFooSymbol = Symbol(‘foo‘); console.log(fooSymbol == otherFooSymbol); //false
let fooGlobalSymbol = Symbol.for(‘foo‘); //创建新符号 let otherFooGlobalSymbol = Symbol.for(‘foo‘); // 重用已有符号 let localSymbol = Symbol(‘foo‘); console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true console.log(localSymbol === fooGlobalSymbol); // false
// 创建全局符号 let s = Symbol.for(‘foo‘); console.log(Symbol.keyFor(s)); // foo // 创建普通符号 let s2 = Symbol(‘bar‘); console.log(Symbol.keyFor(s2)); // undefined
let s1 = Symbol(‘foo‘), s2 = Symbol(‘bar‘); let o = { [s1]: ‘foo val‘ }; // 这样也可以:o[s1] = ‘foo val‘; console.log(o);// {Symbol(foo): foo val} Object.defineProperty(o, s2, {value: ‘bar val‘}); console.log(o);// {Symbol(foo): foo val, Symbol(bar): bar val} Object.defineProperties(o, { [s3]: {value: ‘baz val‘}, [s4]: {value: ‘qux val‘} });
注:几个查询属性的函数
// 以下面对象为例子
let s1 = Symbol(‘foo‘), s2 = Symbol(‘bar‘); let o = { [s1]: ‘foo val‘, [s2]: ‘bar val‘, baz: ‘baz val‘, qux: ‘qux val‘ };
函数名 | 返回值 |
---|---|
Object.getOwnPropertySymbols(o) | [Symbol(foo), Symbol(bar)] |
Object.getOwnPropertyNames(o) | ["baz" , "qux"] |
Object.getOwnPropertyDescriptors(o) | {baz: {...}, qux: {...}, Symbol(foo): {...}, Symbol(bar): {...}} |
Reflect.ownKeys(o) | ["baz" , "qux" , Symbol(foo), Symbol(bar)] |
class Emitter { constructor(max) { this.max = max; this.asyncIdx = 0; } async * [Symbol.asyncIterator]() { while(this.asyncIdx < this.max) { yield new Promise((resolve) => resolve(this.asyncIdx++)); } } } // 用于调用异步迭代器的异步函数 async function asyncCount() { let emitter = new Emitter(5); for await(const x of emitter) { console.log(x); } } asyncCount(); // 0 // 1 // 2 // 3 // 4
function Foo() {} let f = new Foo(); console.log(Foo[Symbol.hasInstance](f)); // true //也可使用 instanceof console.log(f instanceof Foo); // true
let initial = [‘foo‘]; let array = [‘bar‘]; console.log(array[Symbol.isConcatSpreadable]); //undefined console.log(initial.concat(array)); // [‘foo‘, ‘bar‘] 数组对象本身默认打平 array[Symbol.isConcatSpreadable] = false; console.log(initial.concat(array)); // [‘foo‘,Array(1)] 改变默认行为 let arrayLikeObject = {length: 1, 0: ‘baz‘ }; console.log(arrayLikeObject[Symbol.isConcatSpreadable]);//undefined console.log(initial.concat(arrayLikeObject));// [‘foo‘, {...}] arrayLikeObject[Symbol.isConcatSpreadable] = true; console.log(initial.concat(arrayLikeObject));// [‘foo‘,‘baz‘] 类数组对象true有效 let otherObject = new Set().add(‘qux‘); console.log(otherObject[Symbol.isConcatSpreadable]);//undefined console.log(initial.concat(otherObject)); //[‘foo‘, Set(1)] otherObject[Symbol.isConcatSpreadable] = true; console.log(initial.concat(otherObject)); //[‘foo‘] 非类数组导致忽略
class Emitter { constructor(max) { this.max = max; this.idx = 0; } *[Symbol.iterator]() { while(this.idx < this.max) { yield this.idx++; } } } function count() { et emitter = newEmitter(5); for (const x of emitter) { console.log(x); } } count(); // 0 // 1 // 2 // 3 // 4
对象其实就是一组数据和功能的集合
let o = new Object(); let o = new Object; // 合法,但不推荐
每个Object实例都拥有的属性和方法(方法都在Object的原型上)
属性/方法 | 说明 |
---|---|
constructor | 值为用于创建当前对象的函数。 |
hasOwnProperty(propertyName) | 用于判断当前对象实例(不是原型)上是否存在给定的属性。 要检查的属性名必须是字符串或符号。 |
isPrototypeOf(object) | 用于判断当前对象是否为另一个对象的原型 例:Foo.prototype.isPrototypeOf(foo) //true |
propertyIsEnumerable(propertyName) | 用于判断给定的属性是否可以使用for-in语句枚举 |
toLocaleString() | 返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。 |
toString() | 返回对象的字符串表示。 |
valueOf() | 返回对象对应的字符串、数值或布尔值表示。通常与toString()的返回值相同。 |
注意:浏览器环境中的BOM和DOM对象都是由宿主环境定义和提供的宿主对象。 而宿主对象不受ECMA-262约束,所以它们可能会也可 能不会继承Object。
此处略
// backupObject 为备用值 // 当preferredObject为undefined或null时使用 let myObject = preferredObject || backupObject;
特殊情形 | 返回值 |
---|---|
乘积超过范围 | Infinity或-Infinity |
任意操作数为NaN | NaN |
Infinity乘以0 | NaN |
Infinity乘以非0的有 限数值 | Infinity或-Infinity |
Infinity乘以(正负)Infinity | Infinity或-Infinity |
特殊情形 | 返回值 |
---|---|
商超过范围 | Infinity或-Infinity |
任意操作数为NaN | NaN |
Infinity除以Infinity | NaN |
0除以0 | NaN |
非0常数除以0 | Infinity或-Infinity |
Infinity除以任何数值 | Infinity或-Infinity |
特殊情形 | 返回值 |
---|---|
Infinity除以有限值 | NaN |
有限值除以0 | NaN |
Infinity除以Infinity | NaN |
有限值除以Infinity | 有限值(被除数) |
0除以非0 | 0 |
Math.pow()现 在有了自己的操作符**
console.log(Math.pow(3, 2)); //9 console.log(3 ** 2); //9
包括小于 (<)、大于(>)、小于等于(<=)和大于等于 (>=)
如果都是字符串则比较字符编码
其他情况——期待操作数都是数字,除了对象的其他类型会执行Number() 转换为数字。
如果是对象,有valueOf() 就只调用valueOf(),没有就调用toString() 再调用Number()
等于、不等于和全等、不全等
a?b:c
条件(a)为真,表达式值为b,否则为c
用来在一条语句中执行多个操作,值为表达式的最后一个值
标签语句用于给语句加标签,可以在后面通过 break或continue语句引用。
let num = 0; outermost: for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { if (i == 5 && j == 5) { break outermost; } num++; } } console.log(num); // 55
with语句的用途是将代码作用域设置为特定的对象
let qs = location.search.substring(1); let hostName = location.hostname; let url = location.href; // 下方等价 with(location) { let qs = search.substring(1); let hostName = hostname; let url = href; }
注:由于with语句影响性能且难于调试其中的代 码,通常不推荐在产品代码中使用with语句。
可以 使用 switch(true) 然后使用类似 case num>0: 增加更多逻辑
原文:https://www.cnblogs.com/ku1a/p/14741824.html