当前位置: 首页 > news >正文

网站内容体系宁波seo排名优化教程

网站内容体系,宁波seo排名优化教程,400平别墅装修费用,注册网站会员违法文章目录 DOM (Document Object Model)BOM (Browser Object Model) let 和 const 命令constObject.freeze方法跨模块常量全局对象的属性 变量的结构赋值数组结构赋值对象解构赋值字符串解构赋值数值和布尔值的解构赋值函数参数解构赋值圆括号的问题 解构赋值的用途 字符串的扩展… 文章目录 DOM (Document Object Model)BOM (Browser Object Model) let 和 const 命令constObject.freeze方法跨模块常量全局对象的属性 变量的结构赋值数组结构赋值对象解构赋值字符串解构赋值数值和布尔值的解构赋值函数参数解构赋值圆括号的问题 解构赋值的用途 字符串的扩展Unicode 表示方法codePointAt()String.fromCodePoint()字符串遍历接口at()normalize()includes(), startsWith(), endsWith()repeat()padStart(), padEnd()模板字符串实例模板编译 正则表达式正则表达式标志正则表达式模式基本字符类字符集和范围量词边界匹配捕获组和非捕获组 正则表达式方法RegExp.prototype.testRegExp.prototype.execString.prototype.matchString.prototype.replaceString.prototype.splitString.prototype.search 例子验证邮箱地址1. ^ 字符串开始2. [a-zA-Z0-9._%-] 本地部分3. 电子邮件的分隔符4. [a-zA-Z0-9.-] 域名部分5. \. 点号6. [a-zA-Z]{2,} 顶级域名7. $ 字符串结束提取日期1. (\d{4}) 年份部分2. - 分隔符3. (\d{2}) 月份部分4. - 分隔符5. (\d{2}) 日期部分 RegExp 构造函数u标志y标志 数值Number.parseInt(), Number.parseFloat()Number.isInteger() 函数箭头函数1. **foo() 调用方式**2. **foo.call({id: 42}) 调用方式**关键区别总结示例对比示例 1: foo()示例 2: foo.call({id: 42}) 构造函数 VS 普通函数1. **函数名称的约定**2. **new 关键字**3. **this 绑定**4. **返回值**5. **使用场景**总结 函数绑定1. **Function.prototype.bind() 方法**2. **.call() 和 .apply() 方法**3. **箭头函数的 this 绑定**总结:: 函数绑定运算符 JavaScript 包含了 ECMAScript、DOM、BOM。 DOM (Document Object Model) DOM 浏览器特有。 定义: DOM 是一种编程接口用于访问和操作网页的内容和结构。它将网页的内容表示为一个树状结构使得 JavaScript 可以动态地访问和更新网页内容、结构和样式。主要功能: 节点: 通过 DOM网页的每个部分如元素、属性和文本都可以视为一个节点。节点操作: JavaScript 可以创建、修改、删除和替换这些节点。事件处理: 通过 DOM可以为网页中的事件如点击、输入、加载等添加事件监听器。 BOM (Browser Object Model) 定义: BOM 是用于与浏览器窗口及其功能进行交互的一组对象和方法。它允许 JavaScript 访问和操作浏览器窗口、文档、历史记录、导航、位置等。主要功能: window 对象: 代表浏览器窗口提供了访问浏览器属性和方法的能力例如 alert(), confirm(), prompt(), setTimeout(), clearTimeout() 等。navigator 对象: 提供关于浏览器的信息如浏览器版本和用户代理。screen 对象: 提供关于显示屏的分辨率和尺寸的信息。history 对象: 允许你访问和操作浏览器的历史记录。location 对象: 允许你访问和修改浏览器的 URL。 ECMA Script 6 let 和 const 命令 {let a 10; //let声明只在其所在的代码块有效var b 1; } a b//run: a ^ReferenceError: a is not definedfor(let i 0; i 10; i){} //for循环中的局部变量 let iconsole.log(i)//run: console.log(i)^ReferenceError: i is not definedvar a [] for (var i 0; i 10; i) { //var i 全局变量a[i] function() {console.log(i);} } a[6](); //10var a [] for (let i 0; i 10; i) { //let i 全局变量a[i] function() {console.log(i);} } a[6](); //6变量提升 var 存在变量提升。let 不存在。 console.log(a); //变量一定要在声明后使用 let a 2;//run: console.log(a);^ReferenceError: Cannot access a before initializationconsole.log(a); var a 2;//run: undefined暂时性死区 var tmp 123;if (true) {tmp abc;let tmp; //let const 封闭作用域 }//run:tmp abc;^ReferenceError: Cannot access tmp before initializationif (true){//暂时性死区 TDZ 开始tmp abc;console.log(tmp);let tmp; //TDZ temporal dead zone 结束console.log(tmp); //undefinedtmp 123;console.log(tmp); //123 }//run: D:\jsPro\work\test.js:3tmp abc;^ReferenceError: Cannot access tmp before initializationfunction bar(x y, y 2) { //(x 2, y x)return [x,y]; } bar();//run: function bar(x y, y 2) {^ReferenceError: Cannot access y before initialization变量不能重复声明 function() {let a 10;var a ; //error }function() {let a 10;let a 1; //error }function func(arg) {let arg; //error }function func(arg) {{ //局部作用域let arg; //correct} }块级作用域 function f1() {let n 5;if (true) {let n 10;}console.log(n) //5 }{let a secret;function f() {console.log(inner)return a;} } f()//run: PS D:\jsPro\work node test.js inner //块级作用域外可以调用块级作用域内的函数ES6 书里面写的这里会报错let f; {let a secret;f function () {return a;} } console.log(f());//run: PS D:\jsPro\work node test.js secretconst const PI 3.14; //常量值不可改变声明时必须初始化只在声明的块级作用域以内有效不存在变量提升存在暂时性死区只能在声明后使用。const foo {}; //foo是常量指向的地址不变但里面的数据可变对象声明为常量需要小心。foo.prop 123;const a []; a.push(Hello);const a []; a.push(Hello); a.length 0; a [Dave];//run: a [Dave];^TypeError: Assignment to constant variable.var a []; var b [];b.push(hello); b.push(world)console.log(b)a bconsole.log(a)//run: PS D:\jsPro\work node test.js [ hello, world ] [ hello, world ]Object.freeze方法 const foo Object.freeze({});foo.prop 123; //不会添加新属性console.log(foo)//run: PS D:\jsPro\work node test.js {}//将一个对象彻底冻结 var constantize (obj) {Object.freeze(obj);Object.keys(obj).forEach( (key, value) {if (typeof obj[key] object) {constantize(obj[key]);}}) }Object.freeze() 只会冻结对象的第一层。如果对象的属性值也是对象嵌套对象这些嵌套对象不会被自动冻结。 var constantize (obj) {Object.freeze(obj); // 冻结对象防止对其进行任何修改Object.keys(obj).forEach((key) { // 遍历对象的所有键if (typeof obj[key] object) { // 如果值是对象constantize(obj[key]); // 递归调用 constantize 函数}}); }// 创建一个包含嵌套对象的示例对象 const myObject {name: John,age: 30,address: {city: New York,zip: 10001},hobbies: [reading, gaming] };// 调用 constantize 函数 constantize(myObject);// 尝试修改对象将会失败因为对象已经被冻结 myObject.name Jane; // 无效 myObject.address.city Los Angeles; // 无效 myObject.hobbies.push(swimming); // 无效console.log(myObject);run: myObject.hobbies.push(swimming); // 无效^TypeError: Cannot add property 2, object is not extensible这个错误说明 myObject.hobbies 数组已经被冻结无法对其进行修改如添加新元素。 跨模块常量 export const A 1; export const B 2; export const C 3;全局对象的属性 全局对象是最顶层的对象。浏览器环境中指的是 window对象。node.js 中指 global 对象。 var 命令和 function 命令声明的全局变量依旧是全局对象的属性let 命令、const 命令 和 class 命令声明的全局变量不属于全局对象的属性。 var a 1; //node.js 中可以写成 global.a 或者写成 this.a window.avar a 1; console.log(a) //1this.a 2 console.log(this.a, a) //2 1window.a 3 console.log(window.a, this.a, a) //ReferenceError: window is not defined //nodejs 环境中没有 window 对象run: PS D:\jsPro\work node test.js 1 2 1 D:\jsPro\work\test.js:7 window.a 3 ^ReferenceError: window is not defined变量的结构赋值 数组结构赋值 var [a, b, c] [1, 2, 3];console.log(a,b,c) //1, 2, 3嵌套解构赋值 let [foo, [[bar], baz]] [1,[[2], 3]];console.log(a,b,c) //1, 2, 3let [ , , third] [1,2,3] console.log(third) //3let [x, ,y] [1,2,3]; console.log(x, y); //1 3let [head, ...tail] [1,2,3,4,5]; console.log(head, tail)//run: 1 [ 2, 3, 4, 5 ]let [x, y, ...z] [a]; console.log(x, y, z)//run: a undefined []不完全解构 let [x, y] [1,2,3]; console.log(x, y) //1 2 let [a, [b], d] [1, [2,3],4]; console.log(a,b,d) //1 2 4var [x, y, z] new Set([a, b, c]); console.log(x, y, z); //a b cfunction* fibs() {var a 0;var b 1;while (true) {yield a;[a,b] [b, a b];} }var [a, b, c, d, e, f, g] fibs();console.log(a, b, c, d, e, f, g) //斐波那契数列function\* fibs(): 定义了一个生成器函数 fibs它会生成斐波那契数列的数字。 yield a;: yield 关键字会暂停函数执行并返回当前的 a 值。每次调用 next() 时函数会从这里继续执行。 [a, b] [b, a b];: 使用解构赋值更新 a 和 b 的值。a 被更新为 bb 被更新为 a b这是生成下一个斐波那契数所需的操作。 解构赋值默认值 var [foo true] []; console.log(foo)use strict; var [x, y b] [a]; console.log(x, y) //a b var [m, n b] [a, undefined]; console.log(m, n) //a bvar [x 1] [undefined]; console.log(x) //x 1var [x 1] [null]; console.log(x) // x null , null不严格等于undefined默认值不会生效function f() {console.log(aaa); }let [x f()] [1]; //默认值是表达式惰性求值只有在用到的时候求值相当于 let x; if ([1][0] undefined) {x f(); } else {x [1][0] }console.log(x)function f() {console.log(aaa); }var [x f()] [undefined]; //aaafunction f() {return aaa; }let arr [1]; let x arr[0] undefined ? f() : arr[0]; console.log(x) //1function f() {return aaa; }let arr [undefined]; let x arr[0] undefined ? f() : arr[0]; console.log(x) //aaa对象解构赋值 var {foo, bar} {foo: aaa, bar: bbb}; console.log(foo, bar); //aaa bbbvar {bar, foo} {foo: aaa, bar: bbb}; console.log(foo, bar); //aaa bbb 和次序无关按属性名赋值var {baz} {foo: aaa, bar: bbb}; baz //undefinedvar {foo: baz} {foo: aaa, bar: bbb}; console.log(baz) // foo的属性值赋值给新变量 bazlet obj { first: hello, last: world}; let {first: f, last: l} obj; console.log(f, l) //hello worldvar {foo: foo, bar: bar} {foo: aaa, bar: bbb}; //完整写法 var {foo, bar} {foo: aaa, bar: bbb}; //省略属性名写法let foo; ({foo} {foo: 1}); console.log(foo) //1let baz; ({bar:baz} {bar: 1}) console.log(baz) //1嵌套结构的对象 var obj {p: [hello,{y: World}] }; var {p: [x, {y}]} obj; console.log(x, y){ } 和 [ ] 对象使用 {} 来定义表示键值对的集合。用于存储和组织数据例如属性和方法。 const person {name: Alice,age: 30,address: {city: Wonderland,postalCode: 12345} };console.log(person.address.city); // 输出 Wonderland数组使用 [] 来定义表示有序的元素集合。用于存储列表或序列的数据例如索引元素的集合。 const numbers [1, 2, 3, [4, 5, [6, 7]]];console.log(numbers[3][2][1]); // 输出 7var node {loc: {start: {line: 1,column: 5}} };var {loc: {start: {line}}} node; console.log(line) //1 console.log(loc) //loc是模式 console.log(start) //start是模式let obj {}; let arr []; ({foo: obj.prop, bar: arr[0]} {foo: 123, bar: true});console.log(obj, arr); //{ prop: 123 } [ true ]对象解构指定默认值 var {x 3} {}; console.log(x) //3var {x, y 5} {x: 1}; console.log(x, y); //1 5var {message: msg Something went wrong} {}; console.log(msg) //默认值生效的条件是对象的属性严格等于undefinedvar {x 3} {x: undefined}; console.log(x) //3var {x 3} {x: null}; console.log(x) //nullvar {foo} {bar: baz}; console.log(foo) //undefined 解构是被就是undefinedvar x; {x} {x: 1}; //报错{}会解析成一个代码块 console.log(x)var x; ({x} {x:1}); //正确 console.log(x)let {log, sin, cos} Math; //对象的解构赋值可以方便地将现有的对象的方法赋值到多个变量。字符串解构赋值 const [a, b, c, d, e] hello; console.log(a,b,c,d,e) //h e l l olet {length: len} hello; console.log(len) //5数值和布尔值的解构赋值 let {toString: s} 123; console.log(s Number.prototype.toString) //truelet {toString: s} true; console.log(s Boolean.prototype.toString) //true数值和布尔值都有 toString 属性。 解构赋值时等号右边的不是对象就会先转换成对象在进行解构赋值。undefined 和 null 无法转换成对象解构赋值会报错。 let {prop: x} undefined; //TypeError let {prop: y} null; //TypeError函数参数解构赋值 function add([x, y]) { //参数不是数组而是数组经过解构的结果x和yreturn x y; } console.log(add([1,2]));function ad(x, y) {return x y; } console.log(ad(1,2));console.log([[1,2],[3,4]].map(([a,b]) a b)); //[ 3, 7 ]函数参数解构赋值默认值 function move({x 0, y 0} {}) {return [x, y]; } console.log(move({x:3, y:8})); console.log(move({x: 3})); console.log(move({})) console.log(move())//run: [ 3, 8 ] [ 3, 0 ] [ 0, 0 ] [ 0, 0 ]function move({x, y} {x: 0, y: 0}) { //函数的默认值区别于函数参数解构赋值的默认值return [x, y]; } console.log(move({x:3, y:8})); console.log(move({x:3})); console.log(move({})) console.log(move())//run: [ 3, 8 ] [ 3, undefined ] [ undefined, undefined ] [ 0, 0 ]undefined 会触发函数参数的默认值。 console.log([1, undefined, 3].map((x yes) x)); //run: [ 1, yes, 3 ]圆括号的问题 //全部报错变量声明语句模式不能使用圆括号 var [(a)] [1]; var {x: (c)} {}; var {o: ({p: p})} {o: {p: 2}}; 函数参数中模式不能带有圆括号 //函数参数也属于变量声明不能使用圆括号 function f([(z)]) { return z;}//全部报错 ({p: a}) {p: 42}; ([a]) [5]; [({p: a}), {x:c}] [{},{}];可以使用圆括号的情况 //赋值语句的非模式部分可以使用圆括号以下都是赋值语句而不是声明语句 [(b)] [3]; ({p: (d)} {}); [(parseInt.prop)] [3];解构赋值的用途 交换变量值 [x, y] [y, x];从函数返回多个值 function example() {return [1,2,3]; } var [a, b, c] example(); console.log(a,b,c);//返回一个对象 function example() {return {foo: 1,bar: 2}; } var {foo, bar} example(); console.log(foo,bar);函数参数的定义: 函数参数有序无序的情况下参数都能准确地一一对应 function f([x, y, z]) {console.log(x:${x},y:${y},z:${z}.) } f([1,2,3]) //x:1,y:2,z:3.function f({x, y, z}) {console.log(x:${x},y:${y},z:${z}.) } f({z:3, x:1, y:2}); //x:1,y:2,z:3.提取JSON数据 var jsonData {id: 42,status: ok,data: [867, 5309] } let {id, status, data: number} jsonData; console.log(id, status, number); //42 ok [ 867, 5309 ]函数参数的默认值 jQuery.ajax function (url, {async true,beforeSend function() {},cache true,complete function() {},crossDomain false,global true,//... more config }) {// ... do stuff };函数参数的默认值避免了在函数体内部写 var foo config.foo || default foo; config.foo: 这是一个可能存在的变量或对象属性。如果 config 对象中有一个 foo 属性它的值会被使用。 || (逻辑或运算符): 逻辑或运算符会检查 config.foo 的值。如果 config.foo 是假值undefined、null、false、0、NaN 或空字符串 则 || 运算符会返回其右侧的值。 var config {foo: undefined } var foo config.foo || default foo; console.log(foo) //default foovar config {foo: null } var foo config.foo || default foo; console.log(foo) //default foovar config {foo: 0 } var foo config.foo || default foo; console.log(foo) //default foovar config {foo: false } var foo config.foo || default foo; console.log(foo) //default foovar config {foo: } var foo config.foo || default foo; console.log(foo) //default foovar config {foo: NaN } var foo config.foo || default foo; console.log(foo) //default foo//提供默认值: 当你希望确保一个变量总是有一个有效的值即使原始值不存在或为假值时。 function greet(name) {var displayName name || Guest;console.log(Hello, displayName); }greet(); // 输出 Hello, Guest greet(Alice); // 输出 Hello, Alice假值: 逻辑或运算符 || 只会在左侧值是“假值”时使用右侧的值。假值包括 undefined、null、false、0、NaN 和空字符串 。这意味着如果 config.foo 的值是这些假值中的一个默认值将会被使用。 更严格的默认值: 如果想在 config.foo 为 undefined 或 null 时使用默认值可以使用空值合并运算符 ??在 ES2020 中引入?? 运算符仅在左侧的值为 undefined 或 null 时使用右侧的值。 var config {foo: NaN } var foo config.foo ?? default foo; console.log(foo) //NaNvar config {foo: 0 };var foo config.foo ?? default foo; console.log(foo); // 输出 0遍历 Map 解构: 任何部署了 Iterator 接口的对象可以使用 for … of 循环遍历。Map 原生支持 Iterator 接口。 var map new Map(); map.set(first, hello); map.set(second, world); for (let [key, value] of map) {console.log(key ${key} is ${value}); }只获取键 for (let [key] of map) { ... ...}只获取值 for (let [value] of map) {... ...}输入模块的指定的方法 const { SourceMapConsumer, SourceNode } require(source-map);字符串的扩展 Unicode 表示方法 console.log(\u0061); //a console.log(\uD842\uDFB7); // console.log(\u20BB7); //₻7 console.log(\u{20BB7}); // console.log(\u{41}\u{42}\u{43}); //ABC console.log(hell\u{6F}); //hello console.log(\u{1F680}); // console.log(\uD83D\uDE80); // console.log(\u{1F680} \uD83D\uDE80) //truejavascript 6 中方法表示字符 z console.log(\z z); //true console.log(\172 z); //true console.log(\x7A z); //true console.log(\u007A z); //true console.log(\u{7A} z) //truecodePointAt() JavaScript 内部 字符格式 UTF-16两个字节。需要4个字节存储的字符码点大于 0xFFFF 的字符JavaScript 认为是两个字符。 var s ; let {length: len} s; console.log(len) console.log(s.charAt(0)); console.log(s.charAt(1)); console.log(s.charCodeAt(0)); console.log(s.charCodeAt(1));//run: 255362 57271var s a; console.log(s.codePointAt(0)); console.log(s.codePointAt(1)); console.log(s.codePointAt(2)); console.log(s.codePointAt(0).toString(16)); console.log(s.codePointAt(2).toString(16))//run: 134071 57271 97 20bb7 61var s a; for (let ch of s) {console.log(ch.codePointAt(0).toString(16)); } //run: 20bb7 61//判断一个字符是否占4个字节 function is32Bit(c) {return c.codePointAt(0) 0xFFFF; }console.log(is32Bit()); //true console.log(is32Bit(a)); //falseString.fromCodePoint() //码点值到字符转换 console.log(String.fromCodePoint(0x20BB7)) //console.log(String.fromCodePoint(0x78, 0x1f680, 0x79)) console.log(x\uD830\uDE80y) console.log(String.fromCodePoint(0x78, 0x1f680, 0x79) x\uD83D\uDE80y)//run: xy xy true字符串遍历接口 for (let ch of foo) {console.log(ch) }var text String.fromCodePoint(0x20BB7); for (let i 0; i text.length; i) { //普通遍历无法遍历码点大于 0xFFFF的字符console.log(text[i]) }//run:at() console.log(abc.charAt(0)); //a console.log(.charAt(0)); // ECMAScript 7 将支持码点大于 0xFFFF 的字符chrome已经支持normalize() console.log(\u01D1); console.log(\u004F\u030c); console.log(\u01D1 \u004F\u030c) console.log(\u01D1.length) console.log(\u004F\u030c.length)//run: Ǒ //单独字符 Ǒ //合成字符 false 1 2console.log(\u01D1.normalize() \u004F\u030c.normalize()) //true //normalize() Unicode 正规化将字符的不同表示方法统一为同样的形式。normalize() 参数 NFC默认参数标准等价合成Normalization Form Canonical Composition)返回多个简单字符的合成字符。标准等价 指 视觉和语义上的等价。NFDDecomposition标准等价分解将 NFC 的合成分解成多个简单字符。NFKC兼容等价合成Normalization Form Compatibility Composition返回合成字符语义等价视觉不等价。NFKD兼容等价分解NFKC 逆过来。 console.log(\u004f\u030c.normalize(NFC).length) console.log(\u004f\u030c.normalize(NFD).length) //run: 1 2includes(), startsWith(), endsWith() var s helloWorld.js;s.startsWith(hello); //true s.endsWith(.js); //true s.includes(oWor); //truerepeat() x.repeat(5); //xxxxx hello.repeat(2); //hellohello let a zero; console.log(start${a.repeat(0)}end); //startendlet a zero; console.log(a.repeat(2.9)); //zerozero 小数向下取整let a Zero; console.log(a.repeat(2)); //ZeroZeropadStart(), padEnd() for (let i 1; i 14; i) {console.log(String(i).padStart(3, 0)); } //run: 001 002 003 004 005 006 007 008 009 010 011 012 013for (let i 1; i 14; i) {console.log(String(i).padStart(5, ab)); } //run: abab1 abab2 abab3 abab4 abab5 abab6 abab7 abab8 abab9 aba10 aba11 aba12 aba13for (let i 1; i 14; i) {console.log(String(i).padEnd(5, ab)); } //run: 1abab 2abab 3abab 4abab 5abab 6abab 7abab 8abab 9abab 10aba 11aba 12aba 13aba模板字符串 //使用 jQuery 进行 DOM 操作将字符串内容追加到一个 HTML 元素中。 //传统写法 $(#result).append(There are b basket.count /b items in your basket, em backet.onSale /em are on sale! ); //ES6写法 $(#result).append(There are b${basket.count}/bitems in your basketem${backet.onSale}/em are on sale! ); // 反引号 包裹的字符串镶嵌变量镶嵌格式 ${变量名}取变量里面的值替换 ${变量名} 放在原字符串里面。//反引号里的字符换可以换行保留原有格式 console.log(abcd1234yesno) //字符换原模原样输出包括空格、换行等//run: abcd1234yesnovar x 1; var y 2; console.log(x y ${x y});var obj {x: 1,y:2 };console.log(the sum of x and y in obj is ${obj.x obj.y});function fn() {return hello world; } console.log(start ${fn()} end); //start hello world end引用模板字符串本身 写法一 let str return Hello ${name}!; // 用作函数体 let func new Function(name, str); //构造函数 console.log(func(Jack))new Function(name, str) 创建了一个新的函数。new Function() 是一个构造函数用于动态创建 JavaScript 函数。这个构造函数允许代码在运行时生成新的函数函数体的代码以字符串形式提供。 写法二 let str (name) Hello ${name}!; //字符串的内容是一个箭头函数 //箭头函数接收一个name参数返回 Hello ... let func eval.call(null, str); console.log(func(Jack));在 JavaScript 中箭头函数是一种简洁的函数表示方式可以使用 定义。 eval 是一个全局函数它会将字符串作为 JavaScript 代码执行。在这里eval 被用来将 str 变量中的字符串解析为实际的 JavaScript 函数。 eval.call(null, str) 的作用是将 str 作为参数传递给 eval 函数执行call(null, ...) 是为了确保 eval 的上下文 (this) 被设置为 null。在这种情况下this 的值是无关紧要的但使用 call 可以确保 eval 的上下文不会受到干扰。 eval 执行后str 字符串中的箭头函数会被解析为一个真正的 JavaScript 函数并赋值给变量 func。 实例模板编译 模板编译是一个将模板字符串通常包含动态数据插值和逻辑代码转换成可执行的 JavaScript 代码的过程。这个过程的目的是生成最终的 HTML 代码或其他格式的输出以便于动态内容的渲染。 var template ul% for(var i0; i data.supplies.length; i) {%li% data.supplies[i] %/li% } % /ul ; //这个代码片段定义了一个模板字符串它包含 HTML 结构和嵌入的 JavaScript 逻辑。模板引擎会将这个模板字符串编译成一个函数函数可以接受数据并生成动态的 HTML 内容。% ... %: 这是一个包含 JavaScript 逻辑的代码块。这个块内的代码会被执行但不会直接输出到结果中。 在这个例子中使用了一个 for 循环来遍历 data.supplies 数组的元素。 % ... %: 这是一个输出表达式用于将 JavaScript 表达式的结果插入到模板中。在这个例子中它将 data.supplies[i] 的值插入到 li 元素中。 编译和渲染 要将这个模板字符串转换为实际的 HTML需要使用模板引擎将其编译成函数并将数据传递给这个函数进行渲染。许多 JavaScript 模板引擎如 Underscore.js, EJS, Handlebars, 或 Mustache都提供了这种功能。 const {JSDOM} require(jsdom); //npm install jsdomconst dom new JSDOM( !DOCTYPE html htmlhead/headbodydiv idmyDiv/div/body /html)const { window } dom;var template ul% for(var i0; i data.supplies.length; i) {%li% data.supplies[i] %/li% } % /ul ; //模板字符串// echo(ul); // for (var i0; i DataTransfer.supplies.length; i) { // echo(li); // echo(data.supplies[i]); // echo(/li); // }; // echo(/ul);function compile(template) {var evalExpr /%(.?)%/g;var expr /%([\s\S]?)%/g;template template.replace(evalExpr, ); \n echo( $1 ); \n echo().replace(expr, ); \n $1 \n echo();template echo( template );;var script (function parse(data){var output ;function echo(html){output html;}${ template}return output;});return script; }const div window.document.getElementById(myDiv);var parse eval(compile(template)); div.innerHTML parse({supplies : [broom, mop, cleaner]});console.log(window.document.documentElement.outerHTML);!DOCTYPE html htmlheadscriptalert(Hello,World!);/script/headbodydiv idmyDiv/div/bodyscriptvar template ul% for(var i0; i data.supplies.length; i) {%li% data.supplies[i] %/li% } %/ul;function compile(template) {var evalExpr /%(.?)%/g;var expr /%([\s\S]?)%/g;template template.replace(evalExpr, ); \n echo( $1 ); \n echo().replace(expr, ); \n $1 \n echo();template echo( template );;var script (function parse(data){var output ;function echo(html){output html;}${ template}return output;});return script;}var parse eval(compile(template));var div this.document.getElementById(myDiv);div.innerHTML parse({supplies: [broom, mop, cleaner]});/script /html正则表达式 Regular Expressions (regex) 用于匹配、查找和替换字符串中字符模式的工具。 创建正则表达式 使用斜杠 (/) 包围正则表达式的模式 let regex /pattern/flags;pattern 是正则表达式的模式。 flags 是可选的标志用于控制正则表达式的行为。 构造函数 可以通过 RegExp 构造函数动态创建正则表达式 let regex new RegExp(pattern, flags);正则表达式标志 g: 全局匹配不仅匹配第一个还匹配所有符合条件的字符串。 i: 忽略大小写匹配。 m: 多行匹配使 ^ 和 $ 匹配行的开头和结尾。 s: 点号.匹配包括换行符在内的所有字符。 u: Unicode 模式支持 Unicode 字符集。 y: 粘附模式确保正则表达式从指定的位置开始匹配。 正则表达式模式 基本字符类 \d: 匹配数字等价于 [0-9]。\D: 匹配非数字字符。\w: 匹配字母、数字和下划线等价于 [a-zA-Z0-9_]。\W: 匹配非字母、数字和下划线字符。\s: 匹配任何空白字符空格、制表符、换行符等。\S: 匹配非空白字符。 字符集和范围 [abc]: 匹配字符 a、b 或 c。[^abc]: 匹配除了字符 a、b 或 c 之外的字符。[a-z]: 匹配小写字母中的任何一个。 量词 \*: 匹配前面的字符零次或多次。: 匹配前面的字符一次或多次。?: 匹配前面的字符零次或一次。{n}: 匹配前面的字符恰好 n 次。{n,}: 匹配前面的字符至少 n 次。{n,m}: 匹配前面的字符至少 n 次但不超过 m 次。 边界匹配 ^: 匹配输入字符串的开始。$: 匹配输入字符串的结束。 捕获组和非捕获组 (): 捕获组用于提取匹配的子字符串。(?:): 非捕获组用于分组但不捕获匹配的内容。 正则表达式方法 RegExp.prototype.test 测试一个字符串是否匹配正则表达式 let regex /hello/; console.log(regex.test(hello world)); // 输出: trueRegExp.prototype.exec 执行正则表达式匹配返回一个数组或 null let regex /(\d)/; let result regex.exec(The number is 42); console.log(result); // 输出: [ 42, 42, index: 16, input: The number is 42, groups: undefined ]String.prototype.match 使用正则表达式匹配字符串返回匹配结果的数组 let str The numbers are 42 and 37; let regex /\d/g; let result str.match(regex); console.log(result); // 输出: [ 42, 37 ]String.prototype.replace 使用正则表达式替换字符串中的匹配项 let str Hello world; let result str.replace(/world/, there); console.log(result); // 输出: Hello thereString.prototype.split 使用正则表达式拆分字符串 let str one, two, three; let result str.split(/,\s*/); console.log(result); // 输出: [ one, two, three ]String.prototype.search 返回值: 返回第一个匹配的索引位置从 0 开始如果没有匹配项则返回 -1。 只能使用正则表达式的特性: search 方法只支持正则表达式并且不能使用正则表达式的 g全局 标志。如果提供的正则表达式有 g 标志search 方法会忽略这个标志。 let str Hello world!; let index str.search(/world/); console.log(index); // 输出: 6 (world 在字符串中的起始位置是第 6 个字符)let str Hello World!; let index str.search(/world/i); // 使用 i 标志来忽略大小写 console.log(index); // 输出: 6 (world 在字符串中的起始位置是第 6 个字符)let str Hello!; let index str.search(/world/); console.log(index); // 输出: -1 (没有找到匹配项)例子 验证邮箱地址 let emailRegex /^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$/; console.log(emailRegex.test(exampleexample.com)); // 输出: true1. ^ 字符串开始 含义: 匹配输入字符串的开始部分。确保整个字符串都符合正则表达式的模式。 2. [a-zA-Z0-9._%-] 本地部分 [a-zA-Z0-9._%-] 匹配一个字符集其中包括 a-z所有小写字母A-Z所有大写字母0-9所有数字._%-特殊字符点.、下划线_、百分号%、加号和减号- : 匹配前面的字符集一次或多次。意味着本地部分可以包含一个或多个允许的字符。 3. 电子邮件的分隔符 含义: 匹配电子邮件地址中的 符号用于分隔本地部分和域名部分。 4. [a-zA-Z0-9.-] 域名部分 [a-zA-Z0-9.-] 匹配一个字符集其中包括 a-z所有小写字母A-Z所有大写字母0-9所有数字.点号用于分隔域名部分-减号用于分隔域名的不同部分 : 匹配前面的字符集一次或多次。意味着域名部分可以包含一个或多个允许的字符。 5. \. 点号 含义: 匹配一个实际的点号 .。由于点号在正则表达式中有特殊含义匹配任何字符所以在这里需要用反斜杠 \ 转义表示字面量点号。 6. [a-zA-Z]{2,} 顶级域名 [a-zA-Z] 匹配一个字符集其中包括 a-z所有小写字母A-Z所有大写字母 {2,}: 匹配前面的字符集至少 2 次。表示顶级域名如 .com, .org, .net 等必须包含至少两个字母字符。 7. $ 字符串结束 含义: 匹配输入字符串的结束部分。确保整个字符串都符合正则表达式的模式。 提取日期 let dateRegex /(\d{4})-(\d{2})-(\d{2})/; let dateStr 2024-08-20; let match dateRegex.exec(dateStr); if (match) {console.log(Year: ${match[1]}, Month: ${match[2]}, Day: ${match[3]}); }1. (\d{4}) 年份部分 \d: 匹配一个数字字符相当于 [0-9]。{4}: 表示匹配前面的字符数字恰好 4 次。即匹配 4 位数字。(): 圆括号用于捕获组将匹配的内容存储到一个数组中以便后续引用。在这个例子中它捕获了年份部分。 2. - 分隔符 含义: 匹配一个字面量的连字符 -。用于分隔日期的不同部分年、月、日。 3. (\d{2}) 月份部分 \d: 匹配一个数字字符相当于 [0-9]。{2}: 表示匹配前面的字符数字恰好 2 次。即匹配 2 位数字。(): 圆括号用于捕获组将匹配的内容存储到一个数组中。在这个例子中它捕获了月份部分。 4. - 分隔符 含义: 匹配一个字面量的连字符 -用于分隔日期的不同部分年、月、日。 5. (\d{2}) 日期部分 \d: 匹配一个数字字符相当于 [0-9]。{2}: 表示匹配前面的字符数字恰好 2 次。即匹配 2 位数字。(): 圆括号用于捕获组将匹配的内容存储到一个数组中。在这个例子中它捕获了日期部分。 RegExp 构造函数 var regex new RegExp(xyz, i); //等价于 var regex /xyz/i; //RegExp()接收正则表达式 var regex new RegExp(/xyz/i);var regex /xyz/i; exStr 66623asdfggexyz; console.log(regex.exec(exStr));//run: [ xyz, index: 12, input: 66623asdfggexyz, groups: undefined ]new RegExp(/abc/ig, i).flags //忽略原有标志ig改为 iu标志 // Unicode 模式处理大于 \uFFFF 的Unicode 字符 console.log(\uD83D\uDC2A) // console.log(/^\uD83D/u.test(\uD83D\uDC2A)); //false, \uD83D\uDC2A是一个4字节的字符 console.log(/\uD83D\uDC2A/u.test(asdfaasdf\uD83D\uDC2Afasdfasd)); //true console.log(/^\uD83D/.test(\uD83D\uDC2A)); //true, 不加u标志\uD83D\uDC2A会当成两个字符点字符 . 匹配除换行以外的任意单个字符。码点大于 0xFFFF 的 Unicode 字符点字符不能识别必须加上 u标志。 var s ; console.log(/^.$/.test(s)) //false console.log(/^.$/u.test(s)) //true量词 //使用 u 标志所有两次都会正确识别码点大于 0xFFFF 的Unicode 字符 var ss ; var aa aa; console.log(/a{2}/.test(aa)); console.log(/a{2}/u.test(aa)); console.log(/{2}/.test(ss)); console.log(/{2}/u.test(ss));//run: true true false trueconsole.log(/^\u{3}$/.test(uuu)) //true, u被匹配3次 console.log(/^\u{3}$/u.test(uuu)) //false, \u{3} 被当作一个 Unicode字符预定义模式 // \S匹配所有不是空格的字符 console.log(/^\S$/.test()) //false console.log(/^\S$/u.test()) //true正确返回字符串长度的函数字符串包含Unicode 字符 function codePointLength(text) {var result text.match(/[\s\S]/gu);return result ? result.length : 0; } var s \uD83D\uDC2A; console.log(s.length) // 6, 一个 被当作两个字符 console.log(codePointLength(s)) //3正确返回了字符串的长度字符码点大于 0xFFFFconsole.log(\u004B); // K console.log(\u212A); // K 非规范的字符 K console.log(/[a-z]/i.test(\u212A)); //false 无法识别非规范字符 K console.log(/[a-z]/iu.test(\u212A)); // truey标志 y标志 - 粘连sticky。 var s aaa_aa_avar r1 /a/g; //a匹配一次或多次全局匹配 var r2 /a/y; //a匹配一次或多次粘连匹配console.log(r1.exec(s)); //[aaa] console.log(r2.exec(s)); //[aaa]console.log(r1.exec(s)); //[aa] console.log(r2.exec(s)); // nullvar r /a_/y; console.log(r.exec(s)); //[aaa_] console.log(r.exec(s)); //[aa_]//run: [ aaa, index: 0, input: aaa_aa_a, groups: undefined ] [ aaa, index: 0, input: aaa_aa_a, groups: undefined ] [ aa, index: 4, input: aaa_aa_a, groups: undefined ] null [ aaa_, index: 0, input: aaa_aa_a, groups: undefined ] [ aa_, index: 4, input: aaa_aa_a, groups: undefined ]g标志后一次匹配从上一次匹配成功的下一个位置开始剩余的字符串中只要有符合正则表达式的就匹配。 y标志后一次匹配从上一次匹配成功的下一个位置开始但是要连在一起中间不能有其他字符上面的案例中中间有个 _ 字符。 y标志的应用和 g标志相比使用y标志可以发现被匹配字符串之间非法的字符。例如从字符串提取 token 词元y标志确保匹配之间不会有漏掉的字符。 sticky 属性 // 正则表达式是否设置 sticky var regex /hello\d/y; console.log(regex.sticky); //trueflags 属性 // 返回正则表达式的标志 console.log(/abc/ig.flags); //ig console.log(/abc/ig.source); //abc数值 二进制八进制 console.log(0b101 5); // 二进制数值 0b 开头 console.log(0o12 10); // 八进制数值 0o 开头 console.log(Number(0b101), Number(0o12)); //run: true true 5 10Number.isFinite(), Number.isNaN() // infinite adj. 无穷的 // finite adj. 有限的 Number.isFinite(15); // 15 是否有限 Number.isFinite(NaN); // false Not a Number 不是一个数字 NaN Number.isFinite(Infinity); //false Number.isFinite(15); //falseNumber.isNaN(NaN); //true Number.isNaN(666); //false Number.isNaN(999); //false Number.isNaN(true); //falseNumber.parseInt(), Number.parseFloat() Number.parseInt(12.34); //12 Number.parseFloat(3.1415926abc); // 3.1415926Number.isInteger() Number.isInteger(25); //true //是否整数 Number.isInteger(25.0); //true Number.isInteger(25.3); //false Number.isInteger(11); //false Number.isInteger(true); //false函数 通过解构赋值设置默认值 function func({x, y 1}) {console.log(x, y); }func({}); //undefined 1 func({x:1}); //1 1 func({x:1, y:6}); //1 6 func(); //Error直接指定默认值 function func(x, y world) {console.log(x, y); }func(hello); //hello world func(hello, Jackey Song); //hello Jackey Song func(hello, ); //hellofunction fetch(url, { body, methodGET, headers{} }) {console.log(method); }fetch(https://jackey-song.com, {}); //GET 解构赋值参数必须指定 fetch(https://jackey-song.com); //不指定报错function fetch(url, { body, methodGET, headers{} } {}) {console.log(method); }fetch(https://jackey-song.com); //GET 解构赋值指定默认值不报错function f1({x 0, y 0} {}) {console.log(x, y); }function f2({x, y} {x:0, y:0}) {console.log(x, y); }f1(); //0 0 f2(); //0 0f1({x: 5, y:4}); //5 4 f2({x: 5, y:4}); //5 4f1({x: 5}); //5 0 f2({x: 5}) //5 undefinedf1({}); //0 0 f2({}); //undefined undefined指定默认值的参数应当放在最后一个 function func(x, y, z1) {console.log(x, y, z); }func(3,2); //3 2 1function m(x1, y, z) {console.log(x, y, z); }m(2,3); //2 3 undefined m(undefined, 2, 3); //1 2 3 默认值参数放在第一个或中间每次使用默认值都要传个 undefinedfunction n(x, y1, z) {console.log(x, y, z); }n(2, undefined, 3); //2 1 3函数的 length 参数个数 function func(x, y, z1) {console.log(x, y, z); }console.log(func.length) //2 不会算上默认值变量作用域 var x 1; function f(x, y x) {console.log(y); } f(2); //2 z在这里函数的参数x是一个局部变量传入了2y x所以y是2而不是外部的全局变量1console.log(...[1, 2, 3]); //1 2 3函数的name属性: function func() {return 0; }var abc function() { //匿名函数赋值给变量 abcreturn 0; }console.log(func.name); //func 返回函数名 console.log(abc.name); //abcconst f function func() {return 0; } console.log(f.name); //funcvar abc function f() {return 0; } console.log(abc.name); //f箭头函数 使用 定义函数。 var f v v; //等同于 var f function(v) {return v; }var f () 5; //不需要参数使用圆括号 //等同于 var f function() {return 5 }var f (a, b, c) a b c; //多个参数 console.log(f(1,2,3)); //6 //等同于 var f function(a, b, c) {return a b c; }var f (a, b, c) {a a b c; return a**2}; //函数体有多个语句要用花括号返回值要加 return console.log(f(1, 1, 1)); //9var f name ({id: 1, name: name}); //返回值是一个对象对象本身有花括号包裹因此外面需要再加一个圆括号。 console.log(f(Jackey Song)); //{ id: 1, name: Jackey Song }[1,2,3]map(function(x) {return x*x; }); //简写 [1,2,3]map(x x*x);const numbers (...nums) nums; console.log(numbers(1,2,3,4,5)); //[ 1, 2, 3, 4, 5 ]const headAndTail (head, ...tail) [head, tail]; console.log(headAndTail(1,2,3,4,5)); //[ 1, [ 2, 3, 4, 5 ] ]箭头函数没有自己的 this 绑定。它们从定义时的上下文继承 this即箭头函数的 this 是在函数定义时确定的不是调用时确定的。 function Counter() {this.value 0;setInterval(() {this.value; // this 指向 Counter 实例console.log(this.value);}, 1000); //每1000毫秒执行一次 }new Counter();箭头函数不能用作构造函数不能使用 new 关键字实例化对象。 箭头函数没有 arguments 对象。如果需要访问函数的参数可以使用 rest 参数...args。 function traditionalFunction() {console.log(arguments); // [1, 2, 3] }const arrowFunction () {// console.log(arguments); // 会抛出错误 };traditionalFunction(1, 2, 3); arrowFunction(1, 2, 3); // arguments 在箭头函数中是不可用的由于箭头函数不会创建自己的 this 绑定它们在事件处理程序和其他需要 this 绑定的场景中特别有用。 class MyClass {constructor() {this.name MyClass;}greet() {setTimeout(() {console.log(Hello from ${this.name}); // this 正确地指向 MyClass 实例}, 1000);} }new MyClass().greet();箭头函数不可使用 yield 命令箭头函数不能用作 Generator 函数。 箭头函数不能使用 super 关键字因为它们没有自己的 this因此无法访问父类的构造函数或方法。 class Parent {constructor() {this.name Parent;}method() {return () {console.log(super.method()); // 错误: super 不能在箭头函数中使用};} }class Child extends Parent {constructor() {super();this.name Child;}method() {return Hello from Child;} }const child new Child(); child.method()();function foo() {setTimeout( () {console.log(id:, this.id);}, 100); //100毫秒后执行 }//两种调用方式 foo() foo.call( {id: 42}); //id: 421. foo() 调用方式 接调用函数 foo() 时它会在当前的上下文中执行而不是使用任何特定的 this 值。 function foo() {setTimeout(() {console.log(id:, this.id);}, 100); // 100 毫秒后执行 }foo(); // 在全局上下文中调用this 绑定: 在浏览器中直接调用 foo() 时this 通常会绑定到全局对象 window在严格模式下this 是 undefined。由于在全局上下文中 id 不存在这段代码在浏览器的非严格模式下会输出 id: undefined在严格模式下会抛出错误因为 this 是 undefined无法读取 id 属性。 2. foo.call({id: 42}) 调用方式 当使用 foo.call({id: 42}) 调用函数时foo 会被执行并且 this 会被显式地设置为 call 方法中的第一个参数。 function foo() {setTimeout(() {console.log(id:, this.id);}, 100); // 100 毫秒后执行 }foo.call({id: 42}); // 在指定的上下文中调用this 绑定: 在这种情况下this 在 foo 函数体内会被绑定到 {id: 42} 对象。这意味着箭头函数内部的 this 也是 {id: 42}。因此setTimeout 回调中的 this.id 会正确地输出 42。 关键区别总结 foo(): 直接调用时this 是调用 foo 的上下文全局对象或 undefined特别是在异步操作中如 setTimeoutthis 的绑定可能会与期望的上下文不同。foo.call(context): 使用 call 方法调用时this 被显式地设置为 context 参数。在异步操作中this 的值将根据 call 的参数来确定。 示例对比 示例 1: foo() function foo() {setTimeout(() {console.log(id:, this.id);}, 100); }foo(); // 输出: id: undefined 或者在严格模式下可能报错示例 2: foo.call({id: 42}) function foo() {setTimeout(() {console.log(id:, this.id);}, 100); }foo.call({id: 42}); // 输出: id: 42其他代码 var handler {id: 123456,init: function() {document.addEventListener(click, event this.doSomething(event.type), false); //箭头函数内部的 this 指向 handler 对象},doSomething: function(type) {console.log(Handling type for this.id); //这里的 this 指向全局对象} };function Timer () {this.seconds 0; //this 指向new Timer() 创建的对象setInterval(() this.seconds, 1000); //this 指向该对象 }var timer new Timer(); setTimeout(() console.log(timer.seconds), 3100); //3function foo() {return () {return () {return () {console.log(id:, this.id);};};}; } foo.call({id: 42})()()(); //id: 42 //箭头函数本身没有自己的 this所以无论箭头函数嵌套多少层它都是外层的 this。正因为它没有自己的this所以它不能用作构造函数。构造函数 VS 普通函数 1. 函数名称的约定 构造函数: 构造函数通常以大写字母开头以便与普通函数区分。这是一个约定而非强制规则。例如Person, Car, Timer 等。 function Person(name) {this.name name; }普通函数: 普通函数的名称通常以小写字母开头虽然这并不是强制的但可以帮助区分。例如calculateTotal, printMessage 等。 function calculateTotal(a, b) {return a b; }2. new 关键字 构造函数: 构造函数应使用 new 关键字调用。当用 new 调用构造函数时它会创建一个新对象并将 this 绑定到这个新对象。 const person new Person(Alice); // 使用 new 调用构造函数普通函数: 普通函数不应该用 new 关键字调用。如果用 new 调用普通函数它将不会按预期工作通常会返回 undefined 或导致错误。 const total calculateTotal(5, 10); // 普通函数的调用方式3. this 绑定 构造函数: 在构造函数内部this 指向正在被创建的新对象。构造函数可以将属性和方法添加到这个新对象上。 function Person(name) {this.name name; // this 指向新创建的 Person 对象 }普通函数: 在普通函数中this 的值取决于函数的调用方式。在非严格模式下this 通常指向全局对象在浏览器中是 window在严格模式下this 是 undefined。 function printName() {console.log(this.name); // this 取决于调用上下文 }4. 返回值 构造函数: 构造函数通常不显式返回值。它们自动返回新创建的对象。如果显式地返回一个对象那个对象将作为构造函数的结果被返回。 function Person(name) {this.name name;// 不需要返回值自动返回新对象 }普通函数: 普通函数可以返回任何值包括原始数据类型、对象或其他函数。返回值必须显式地指定。 function add(a, b) {return a b; // 显式返回结果 }5. 使用场景 构造函数: 主要用于创建和初始化对象实例。它们用于定义对象的属性和方法通常通过 new 关键字创建新实例。 function Car(make, model) {this.make make;this.model model; }const myCar new Car(Toyota, Corolla);普通函数: 主要用于执行特定的任务或计算结果。普通函数可以被调用多次但不创建对象实例。 function multiply(a, b) {return a * b; }const result multiply(4, 5);总结 构造函数: 名称以大写字母开头通常为约定。使用 new 关键字调用。在函数内部this 绑定到新创建的对象。通常不显式返回值自动返回新对象。 普通函数: 名称以小写字母开头虽然这不是强制的。不使用 new 关键字调用。this 取决于调用上下文。可以显式返回值。 函数绑定 函数绑定是 JavaScript 中处理 this 的一种机制允许创建一个新的函数并预设其中的 this 值和/或参数。函数绑定主要有三种实现方式Function.prototype.bind() 方法、.call() 和 .apply() 方法的使用以及箭头函数的 this 绑定行为。 1. Function.prototype.bind() 方法 bind() 方法用于创建一个新的函数这个新函数会将 this 绑定到指定的对象并且可以预先设置一些参数。 语法: function.bind(thisArg[, arg1[, arg2[, ...]]])参数: thisArg: 新函数执行时 this 的值。arg1, arg2, …: 预设的参数调用新函数时这些参数会被默认传入。 示例: function greet(greeting, name) {console.log(${greeting}, ${name}!); }const greetHello greet.bind(null, Hello); greetHello(Alice); // 输出: Hello, Alice!在这个例子中greetHello 是一个新的函数它的 this 被绑定为 null并且 greeting 参数被预设为 Hello。调用 greetHello(Alice) 实际上等价于 greet(null, Hello, Alice)。 2. .call() 和 .apply() 方法 call() 和 apply() 方法用于立即调用函数并可以显式地设置函数的 this 值和参数。 call() 方法: function functionName(arg1, arg2, ...) {// function body } functionName.call(thisArg, arg1, arg2, ...);apply() 方法: function functionName(arg1, arg2, ...) {// function body } functionName.apply(thisArg, [arg1, arg2, ...]);区别: call() 接受参数列表。apply() 接受一个参数数组。 示例: function greet(greeting, name) {console.log(${greeting}, ${name}!); }greet.call(null, Hi, Bob); // 输出: Hi, Bob! greet.apply(null, [Hi, Bob]); // 输出: Hi, Bob!在这两个例子中greet 函数的 this 被设置为 null并且传入的参数被分别通过 call() 和 apply() 方法传递。 3. 箭头函数的 this 绑定 箭头函数的 this 绑定规则不同于普通函数。箭头函数不创建自己的 this 上下文它会从外围上下文中继承 this。因此箭头函数中的 this 是静态绑定的在函数创建时就已经确定。 总结 bind(): 创建一个新函数设置 this 和预设参数。不会立即执行。call() 和 apply(): 立即调用函数设置 this 和传递参数。call() 接受参数列表apply() 接受参数数组。 函数绑定是 JavaScript 中处理 this 绑定和函数调用的关键技术在各种上下文中控制 this 的值和行为。 :: 函数绑定运算符 foo::bar; //将::左边的对象作为上下文环境绑定到右边的函数上。 //等同于 bar.bind(foo);foo::bar(...arguments); //等同于 bar.apply(foo, arguments);var method obj::obj.foo; //等同于 var method ::obj.foo;let log ::console.log; //等同于 var log console.log.bind(console);
http://www.dnsts.com.cn/news/268924.html

相关文章:

  • 网站推广的方式包括东莞市义务教育阶段统一招生平台
  • 网站美化php wordpress 漏洞
  • 商城网站建设协议做网站没有学历的人会吗
  • 微信恢复官方网站专业的建站公司都具备什么条件
  • 毕业视频代做网站wordpress如何应用ssl
  • 宁波培训网站建设建设部资质升级网站
  • dede网站地图栏目如何上传文件免费天眼查
  • 网站怎么做结算简洁大气国内企业网站
  • 外贸网站建设行业发展南通网站建设要多少钱
  • 用于网站建设的图片广西桂林电子科技大学
  • 做网站注意事项电子商务网络推广主要做什么
  • vue做网站的好处免费咨询服务合同模板
  • 外贸网站源码多语言wordpress 即时
  • 网站服务器查询工具软件制作
  • 二手车网站开发福州市城乡建设网站张麒蛰
  • 辽源建站公司html编辑器汉化版apk
  • wordpress 开发工具常德网站优化咨询电话
  • 传媒网站源码带手机谁有永久免费的服务器
  • 礼品网站设计wordpress 多重
  • 网站服务器升级需要多久合肥如何做百度的网站
  • 安阳住房与城乡建设局官方网站中国空间站叫什么
  • 网站制作公司获取客户手机网站域名注册
  • 三合一网站模板myapp wordpress
  • 网站建设行业推广公司地址怎么弄在百度上显示
  • 网站建设项目环境影响评价目录电子商务网站建设与管理实验
  • 南昌专业网站建设公司哪家好个人网站模板html 下载
  • WordPress建站详细过程企业网页素材
  • 中国电子系统建设三公司网站一般网站建设大概需要多少钱
  • 企业网站做优化网站建设 艺麟盛世
  • 什么外贸网站开发客户无锡住房建设网站