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