ASP 变量 ES6总结
发布时间:2023-02-16 13:17:12 所属栏目:Asp教程 来源:
导读: let定义的变量,是没有声明提升的。
// 尝试在定义之前,访问
console.log(a); // undefined
console.log(b); // 报错
// 定义变量a和b
var a = 10;
let b = 11;
1.3
// 尝试在定义之前,访问
console.log(a); // undefined
console.log(b); // 报错
// 定义变量a和b
var a = 10;
let b = 11;
1.3
|
let定义的变量,是没有声明提升的。 // 尝试在定义之前,访问 console.log(a); // undefined console.log(b); // 报错 // 定义变量a和b var a = 10; let b = 11; 1.3 不可以重复定义 let定义的变量,不允许重复。var过的变量也不可以let。 var a = 10; var a = 11; // 连续通过var定义多个同名变量,是被允许的。 let a = 11; 1.4 不会挂载到window (undefined) 顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。 ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。 var的全局变量是会被挂载到window身上作为属性存在的。 let的变量,就算是全局也不会挂载到window。 var a = 10; let b = 11; 3console.log(window.a); // 10 console.log(window.b); // undefined 1.5 for循环中 let定义的循环变量,在for循环中,循环时是多少,就是多少。 // 定义一个数组 var arr = []; // 通过let定义 for (let i = 0; i < 10; i++) { arr.push(function() { console.log(i); }); } // 让不同的数组成员执行 结果是输出? arr[0](); // 0 arr[1](); // 1 arr[2](); // 2 arr[3](); // 3 arr[7](); // 7 二:const 定义常量 const是ES6中新增的关键字。用于定义“常量”。常量指的是一直不变的量。 2.1 不可被=修改 1const a = 10; a = 11; // 尝试修改a常量 常量保存对象 // 使用常量保存应用类型的数据 const obj = {}; obj.a = 10; console.log(obj); 结论:const只关心变量是否被=修改。至于变量保存的内容是否变化,const不关心。 2.2 其它特点 const与let一块出来的。所以也遵循let的其它特点: 没有变量声明的提升、不会挂载到window、不可以重复定义。 注:千万不要将循环变量用const来定义。 ******三:******数组的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 以前,为变量赋值,只能直接指定值。 let a = 1; let b = 2; let c = 3; ES6 允许写成下面这样。 // 封装数组 let arr = [1, 2, 3]; // 解构数组 let [a, b, c] = arr; // 等价于 // let a = arr[0]; // let b = arr[1]; // let c = arr[2]; 上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。 本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。 let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3 let [ , , third] = ["foo", "bar", "baz"]; third // "baz" let [x, , y] = [1, 2, 3]; x // 1 y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ['a']; x // "a" y // undefined z // [] 如果解构不成功,变量的值就等于undefined。 let [foo] = []; let [bar, foo] = [1]; 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。 let [x, y] = [1, 2, 3]; x // 1 y // 2 let [a, [b], d] = [1, [2, 3], 4]; a // 1 b // 2 d // 4 如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。 // 报错 let [foo] = 1; let [foo] = false; let [foo] = NaN; let [foo] = undefined; let [foo] = null; let [foo] = {}; ******四:******对象的解构赋值 解构语法: let {key, key1, key2……} = obj; // 如下是一个工厂函数,它将创建对象的代码 封装在函数内部 function createObjectFactory(username, age, sex) { var obj = { username: username, age: age, sex: sex } return obj; } // 其实是将name、age、sex三个形参封装起来。 let obj = createObjectFactory("小白", 13, "女"); 解构: // 以前的解构代码 var username = obj.username; var age = obj.age; var sex = obj.sex; console.log(username, age, sex); // ES6中 针对不同的数据结构,提供了不同的解构方式 var {username, age, sex} = obj; console.log(username, age, sex); 五:字符串5.1 多行字符串 // 现在 let str2 = `<div>大家好,我是一个多行字符串</div> <ul> <li>1</li> <li>1</li> <li>1</li> <li>1</li> <li>1</li> <li>1</li> <li>1</li> <li>1</li> </ul> `; 5.2插值语法 ES6中,在多行字符串中,提供了插值语法: ${} 开辟了一个JS执行环境 内部可以调用任何的JS语法 // 通过ajax请求一个对象回来 let obj = { username: "老王", bank: { title: "最好的我们", content: "隔壁老王" } } // 现在 let str2 = `<div>个人简介</div> <div><span>${obj.username}</span></div> <div><span>${obj.bank.title}</span></div> <div><span>${obj.bank.content}</span></div> `; console.log(str2); 5.3 startsWith str.startsWith(str1, pos); 该方法用于判定一个字符串是否以另外一个字符串开头(或者从指定位置开头) str1: 开头字符串 pos: 指定的位置 下标slice的第一个参数的值 结果:布尔值 如果str的pos下标位置是str1.则返回真。否则返回假。 // 定义一个字符串 let str = "今天天气不错"; // 定义另外一个字符串 let str1 = "今天"; // 判定str1是不是str的开头字符串 let result = str.startsWith(str1); console.log(result); //true 5.4 endsWith str.endsWith(str1, pos); 该方法用于判定一个字符串是否以另外一个字符串结尾(或者从指定位置结尾) str1: 结尾字符串 pos: 指定的位置 slice方法的第二个参数 结果:布尔值 如果str的pos下标位置是str1.则返回真。否则返回假。 // 定义一个字符串 let str = "今天天气不错"; // 定义另外一个字符串 let str1 = "天气"; // 判定 str 是否是以 str1 作为结尾 let result = str.endsWith(str1, 4); console.log(result); //true 5.5 includes str.includes(str1, pos); 该方法用于判定一个字符串是否包含另外一个字符串(或者从指定位置之后是否包含) str1: 被包含的字符串 pos: 截取位置 从该位置开始往后截取 return: 布尔值 如果从该位置开始往后截取的字符串中包含str1字符串,则为真,否则为假。 // 定义一个字符串 let str = "今天天气不错"; // 定义另外一个字符串 let str1 = "天气"; // 判定 str1 是否在str中 let result = str.includes(str1, 2); console.log(result); //true 5.6 repeat str.repeat(num); 该方法用于将str复制num次。 num:被复制的次数 最终的长度:str.length * num; 返回值:被复制之后的新字符串 // 定义一个字符串 let str = "你好"; let str1 = str.repeat(100); console.log(str1, str1.length); 六:对象的新增方法6.1 Object.is 该方法用于判定两者是否全等。 0 === -0 // true Object.is(0, -0); // false 1NaN === NaN // false Object.is(NaN, NaN); // true 6.2 Object.assign Object.assign(target); 该方法用于给某一个对象增加其它对象的属性和方法。 该方法接收任意个参数,第一个是被赋予者。剩余的都是赋予者。 target: 被增加属性和方法的对象 剩余的所有参数都是提供属性和方法的对象。 注:这是浅复制、浅拷贝。 // 定义一个对象 let obj = { }; // 定义一些其它对象 let obj1 = { color: "red", sayHello() { console.log(123); } } // 定义其它对象 let obj2 = { name: "张三", dog: { name: "旺财" } } // 将obj1和obj2所具备的属性和方法交给obj对象 Object.assign(obj, obj1, obj2); // 输出obj console.log(obj); 七:Es6新增数组方法7.1 Array.of 该方法用于定义一个新的数组。 Array.of接收任意个参数,每一个参数都被当做数组的成员去处理。 7.2 Array.from 该方法用于将一个类数组对象,转化为数组。 类数组对象:数字下标、length属性 7.3 find arr.find(handler) 该方法用于模糊查询数组中的成员 handler: 函数 该函数必须返回一个布尔值 该函数中有3个参数:value、index、arr 返回值:返回的是符合handler布尔值表达式的成员 7.4 findIndex arr.findIndex(handler) 该方法用于模糊查询数组中的成员的索引 handler: 函数 该函数必须返回一个布尔值 该函数中有3个参数:value、index、arr 返回值:返回的是符合handler布尔值表达式的成员的索引 如果没有找到,则返回 -1 7.5 数组的内部复制 arr.copyWithin(pos, start, end); 该方法用于数组的内部复制 将数组内的start开始(包含)到end结束(不包含)复制,从pos位置开始粘贴(替换)。 pos: 粘贴(替换)的起始位置 start: 复制的开始位置(包含) end: 复制的结束位置(不包含) 具体用法参考我总结的另一篇文章 八:Symbol ES6之前,一共有6种数据类型:string、number、boolean、undefined、null、object ES6中,新增了一种symbol类型。它表示一种“独一无二的符号”类型。属于值类型。 8.1 定义symbol Symbol函数每执行一次,定义一个symbol数据值。 参数只有说明的作用,没有任何其它作用。 Symbol函数不是一个构造函数,不要使用new、不要使用new、不要使用new。 let s = Symbol("你好"); let s1 = Symbol("你好"); console.log(s); console.log(s1); console.log(s === s1); 8.2 作用 通常是用来解决对象的属性名无法重复的问题。 // 定义对象 let obj = { [s]: "你好", [s1]: "你好1" } console.log(obj); 九:代理 proxy ES6中,新增了一个构造函数,用于生成代理对象。 代理:访问的是对象A,其实访问的是另外一个对象B。 A是B的代理对象。 let proxy = (function() { // 源对象 let star = { name: "胡歌", age: 38, sex: "男", hobby: ["读书", "跑步", "摄影", "旅游"] }; // 代理对象 return new Proxy(star, { // get方法在通过proxy对象进行属性的读取或者访问时,会执行 get: function(star, prop, proxy) { console.log("想要读取属性", arguments); if (prop === "age") { return star[prop] - 10; } return star[prop]; }, // set方法在通过proxy对象进行属性的设置时,会执行 set: function() { console.log("想要设置属性", arguments); } }); })(); 十::Number的新增方法10.1 isNaN 在ES6之前,window身上有一个isNaN方法。 判定一个值是否是NaN 在ES6中,Number身上也增加了一个isNaN方法 判定一个数字是否是NaN // 定义一些值 let num = 1/0; let num1 = 0/0; let num2 = "0"; let num3 = NaN; let num4 = "1asdfdsaf23"; // window.isNaN console.log(window.isNaN(num)); // false console.log(window.isNaN(num1)); // true console.log(window.isNaN(num2)); // false console.log(window.isNaN(num3)); // true console.log(window.isNaN(num4)); // true // Number.isNaN console.log(Number.isNaN(num)); // false console.log(Number.isNaN(num1)); // true console.log(Number.isNaN(num2)); // false console.log(Number.isNaN(num3)); // true console.log(Number.isNaN(num4)); // false 10.2 isFinite window.isFinite 用于判定一个值是否是有限的 Number.isFinite 用于判定一个数字是否是有限的 如果参数不是数字 直接false // 定义一些值 let num = 1/0; let num1 = 0/0; let num2 = "0"; let num3 = NaN; let num4 = "1asdfdsaf23"; // window.isFinite console.log(window.isFinite(num)); // false console.log(window.isFinite(num1)); // false console.log(window.isFinite(num2)); // true console.log(window.isFinite(num3)); // false console.log(window.isFinite(num4)); // false // Number.isFinite console.log(Number.isFinite(num)); // false console.log(Number.isFinite(num1)); // false console.log(Number.isFinite(num2)); // false console.log(Number.isFinite(num3)); // false console.log(Number.isFinite(num4)); // false 10.3 isInteger Number.isInteger 该方法用于判定一个数字是否是整数 // 定义一些值 let num = 1/0; let num1 = 0.0; let num2 = "0"; let num3 = NaN; // Number.isInteger console.log(Number.isInteger(num)); // false console.log(Number.isInteger(num1)); // true console.log(Number.isInteger(num2)); // false console.log(Number.isInteger(num3)); // false 十一:箭头函数11.1 定义 ES6中新增了一种函数,叫做箭头函数。 定义语法: var fun = () => {} 11.2 箭头函数中的this 箭头函数中的this,在定义的时候,就会确定下来。(不是写完代码就能确定的) // 定义箭头函数 var fun = () => { console.log(this); } fun(); // window fun.call(document.body); // window document.onclick = fun; // widnow 如果想要改变箭头函数中的this的指向,就将箭头函数的定义代码放在一个普通函数内。在调用普通函数的时候,改变该函数的this。也就改变了箭头函数的this. // 尝试修改箭头函数中的this function createArrowFun() { // 返回一个箭头函数 return () => { console.log(this); } } var arrowFun1 = createArrowFun(); arrowFun1(); // window var arrowFun2 = createArrowFun.call(document.body); arrowFun2(); // document.body 11.3 参数默认值 ES6中,给所有的函数,添加了参数默认值功能。 语法: function fun(a = x, b = x, c = x) {} // 参数默认值 不仅仅箭头函数拥有 普通函数也拥有 function fun(a = 1, b = 2) { return a + b; } console.log(fun()); // 3 11.4无法作为构造函数 因为ES6中,已经增加了class关键字,所以不需要再使用构造函数去模拟了。而且箭头函数中的this它不变。 // 定义一个箭头函数 let arrowFun = () => { } new arrowFun(); 11.5省略写法 ES6将代码的省略做到了极致。 规则: 1 如果形参中只有一个参数,则可以省略圆括号 2 如果函数体中只有一条代码而且还是返回值,则可以省略{}和return let fun = a => a + 2; console.log(fun(1)); //3 11.6arguments 箭头函数中,取消了arguments 改为使用拓展语法代替 ...arg // 箭头函数中,取消了arguments 改为使用拓展语法代替 let arrowFun = () => { console.log(arguments); } // 调用 arrowFun(); 十二:...语法(拓展语法) ES6中,因为新增了箭头函数,而箭头函数有一个特点就是不可以再使用arguments。所以,想要获取所有的参数,就需要别的方式。...语法就是补充。 12.1 第一种 函数中使用 // 定义函数 function fun(a, b, c, ...arg) { // 通过...语法获取剩余参数 该语法只能够写在最后面 console.log(arg); } // 调用函数 fun(1, 2, 3); fun(1, 2, 3, 4, 5); fun(1, 2, 3, 4, 5, 6, 7); 12.2 第二种 解构时使用 // 定义数组 let arr = [1, 2, 3, 4, 5, 6, 7]; // 解构 只要前3项,剩余的要放入另外一个数组 let [a, b, c, ...d] = arr; console.log(a, b, c, d); 12.3 第三种 传递参数时使用 // 定义数组 let arr = [1, 2, 3, 4]; // 输出数组 console.log(arr); console.log(...arr); 十三:数组的迭代器方法 ES6中,新增了迭代器接口。 13.1 keys方法 该方法用于获取数组的所有的keys 也就是下标、索引 demo1: 获取迭代器对象 // 定义数组 let arr = ["a", "b", "c", "d", "e"]; // 调用keys方法 返回迭代器对象 let iterator = arr.keys(); console.log(iterator); demo2: 迭代器对象调用一次next // 每一次迭代器对象调用next方法 都会返回一次结果 let result1 = iterator.next(); console.log(result1); 本次的输出结果是一个对象,对象中有value属性,就是我们这一次得到的结果。对象中有done属性,表示迭代是否完成。false表示未完成,就可以继续。如果true,表示已经完成。 demo3: 代码多次调用next let result1 = iterator.next(); console.log(result1); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); 13.2 values方法 该方法与keys方法的使用方式一致,区别: keys方法的迭代器对象调用了next之后返回的对象中的value是下标 values方法的迭代器对象调用了next之后返回的对象中的value是成员 let arr = ["a", "b", "c", "d", "e"]; // 调用values方法 返回迭代器对象 let iterator = arr.values(); // 每一次迭代器对象调用next方法 都会返回一次结果 let result1 = iterator.next(); console.log(result1); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); ******13.3 ******entries方法 该方法与keys方法、values方法的使用方式一致,区别: keys方法的迭代器对象调用了next之后返回的对象中的value是下标 values方法的迭代器对象调用了next之后返回的对象中的value是成员 entries方法的迭代器对象调用了next之后返回的对象中的value是长度为2的数组 第一个成员是数组的下标 第二个成员是数组的成员 // 定义数组 let arr = ["a", "b", "c", "d", "e"]; // 调用entries方法 返回迭代器对象 let iterator = arr.entries(); // 每一次迭代器对象调用next方法 都会返回一次结果 let result1 = iterator.next(); console.log(result1); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); 什么叫做迭代器? 定义:给定一种方式,能够顺序的遍历结构内部的数据,同时又不暴露内部结构的方式。 ES6中就定义了一个迭代器接口,并且已经给部分数据结构实现了该迭代器。比如数组。 使用方式: 通常是在数据结构的对象的原型上,定义该迭代器接口的获取方式。在调用了该原型方法之后,会返回迭代器对象。 迭代器对象的使用方式是统一的: iterator.next() 得到的结果的结构也是统一的: {value: xxx, done: boolean} 13.4 for……of循环 该循环是用于循环迭代器、或者实现了迭代器接口的数据结构的。 举例: 调用了数组的keys、values、entries方法之后ASP 变量,得到一个迭代器对象:iterator for (let i of iterator) { i: 返回的对象value属性和done属性中的value的值 } 数组是数据结构,数组实现了迭代器接口:所以我们可以通过for of直接迭代数组 let arr = [1, 2, 3, 4, 5, 6]; for (let i of arr) { i: 成员 } 对象也是数据结构,但是没有实现迭代器接口:所以我们不可以通过for of直接迭代对象 let obj = {}; for (var i of obj) {} 报错:obj is not iterable 13.5 迭代迭代器接口对象 // 定义数组 let arr = ["a", "b", "c", "d", "e"]; // 调用entries方法 返回迭代器对象 let iterator = arr.entries(); // 每一次都手工调用iterator的next 太过繁琐 // 所以 ES6提供了for of循环 for (let i of iterator) { console.log(i); } 迭代实现了迭代器接口的数据结构 // 直接迭代arr for (let i of arr) { console.log(i); } 迭代一个没有实现迭代器接口的数据结构 // 定义对象 let obj = { a: 1, b: 2, c: 3 } // 尝试for of迭代obj for (let i of obj) { } 十四:新的数据结构 Set WeakSet14.1 Set Set是一个新的数据结构,可以认为是一个内容不可重复的数组。 注:初始化的时候,一定要new Set // 定义新的数据结构 let s = new Set([1, 2, 3, 4, 5, 6, 6, 6, 6, 6]); console.log(s); 方法: add:参数是任意类型的值 作用:将Set容器内,增加一个新的成员。 注:一定不可以添加已有的。如果添加的是已有的成员,添加失败。 delete:参数是任意类型的值 作用:将Set容器内,移除一个指定的成员。 如果该成员存在,则移除。 forEach:参数是函数 ES5中的迭代器方法 作用:根据Set成员的个数,执行函数多次。每一次的函数的参数是Set的某一个成员 函数的三个参数:Set的value、Set的key、Set自身 has:参数是任意的值 作用:判定参数是否已经存在于Set内部 clear: 没有参数。 作用:清空Set内部的所有内容。 14.2 WeakSet WeakSet是一个与Set相关的数据结构。 与Set的区别: 1 每一个成员只能是引用类型 2 WeakSet不影响垃圾回收机制 WeakSet所使用的成员,不会导致标记数值的变化。 let ws = new WeakSet([{}, {}]); 非引用类型成员会报错: let ws = new WeakSet([1, 2, 3]); 十五:Map Map是一个超对象。与对象有关。 普通对象的key只能是字符串。 Map对象的key可以是任意类型的值。可以是字符串、是数字、布尔值、undefined、null、symbol、引用类型值。 let map = new Map(); set方法: 接收两个参数 第一个参数是超对象的key。值是任意的。 第二个参数是超对象的value。值也是任意的。 get方法: 接收一个参数 第一个参数是超对象的key。值是任意的 返回值: 该参数key对应的value。 其余方法: 与Set一致。 15.1WeakMap 这是一个弱Map。 与WeakSet一致,WeakSet成员只可以是引用类型。 WeakMap的key,只可以是引用类型。 // 初始化 let wm = new WeakMap(); wm.set("a", "1"); 报错 与WeakSet一致,WeakSet不会影响到垃圾回收机制的判定。 WeakMap也不会。 15.2垃圾回收机制 垃圾:内存中没有用的内容,叫做垃圾。比如定义了一个变量,却从来没有使用。 引用计数: 当开辟一个内存地址时,会根据应用它的具体成员的多少来计算数值。当数值不为0时,依旧被使用。当数值为0时,会被清除掉。 标记清除: 进场和出场:整体内存有一个范围,当开辟一个地址时,如果有变量引用,则视为“进场”。如果变量、元素不再引用,则视为“出场”。 引用计数存在一个问题:如果一个元素身上有事件函数,则当把该元素移除时,元素引用函数,函数引用元素。互相引用,导致数字都不为0.无法被移除。所以委托模式,为了解决这个问题,就不给可能被移除的元素自身添加事件。 15.3setInterval与setTimeout 这两个函数,都是用来开启异步代码。 setInterval的参数函数会按照一定的时间间隔执行。 setTimeout的参数函数到时间之后只执行一次。 返回值: 都是数字。 返回值表示的含义是当前的定时器、延时器在浏览器中的编号。 该数字只有在你想要关闭对应的定时器、延时器时才有用。 注:编号是有顺序可循的,所以可以自己猜要关闭哪个。不推荐。推荐的方式还是使用变量来保存这个编号。 (编辑:我爱资讯网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
