上海哪些做网站,信息流广告怎么投放,深圳建设集团有限公司有分公司吗,建网站的系统前言
《JavaScript高级程序设计》
第1章——什么是JavaScript
DOM将整个页面抽象为一组分层节点。
BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript
2.1 script 元素
元素描述async立即开始下载脚本#xff0c;但不能阻止其他页面动作#…前言
《JavaScript高级程序设计》
第1章——什么是JavaScript
DOM将整个页面抽象为一组分层节点。
BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript
2.1 script 元素
元素描述async立即开始下载脚本但不能阻止其他页面动作比如下载资源或等待其他脚本加载只对外部脚本文件有效charset使用src指定代码字符集很少使用大多数浏览器不在乎它的值crossorigin配置相关CORS(跨源资源共享)设置。默认不使用CORSdefer表示在文档解析和显示完成后再执行脚本只对外部脚本文件有效integrity运行比对接收到的资源和指定的加密签名以验证子资源的完整性(SRISubresource Intergrity)。可以用于确保内容分发网络CDNContent Delivery Network不会提供恶意内容。src包含要执行的代码的外部文件type表示代码中脚本语言的内容类型也称MIMI类型这个值始终是“text/javascript”如果这个值是module则代码会被当作ES6模块而且只有这种时候代码中才能出现import和export关键字。
2.1.3 异步加载脚本
async属性和defer两者都能适用于外部脚本告诉浏览器立即开始下载。
htmlheadtitle异步执行脚本/titlescript async srcmain.js/scriptscript async srcmain1.js/script!--可能先于第一个脚本执行--/headbody/body
/html2.1.4 动态加载脚本
let script document.createElement(script);
script.src gibberish.js;
script.async false;
document.head.appendChild(script);第3章——语言基础
var声明的变量会被提升hoist把所有变量声明都拿到函数作用域顶部在函数退出时被销毁。
//var 提升hoist
function foo(){console.log(age);var age 21;
}
foo();
// ↑上面的相当于提升后的下面↓
function foo(){var age;//把所有变量声明都拿到函数作用域顶部console.log(age);age 21;
}
foo();let声明的范围是块作用域var声明的范围是函数作用域。
//let声明
function f1(){let n 5;if(true){let n 10;}console.log(n); // 5 使用let声明的变量 外层代码块 不受 内层代码块 的影响。
//var声明
function f1(){var n 5;if(true){var n 10;}console.log(n); // 10 使用var定义变量n块作用域下最后输出的值是 内层代码块 的结果。
const声明范围也是块作用域是必须同时初始化变量。
const age kuishou;
if(true){const name zhangsan;
}
console.log(age);//kuisou
console.log(name);//undefined 块作用域只能拿到当前层代码块的结果。注意平时使用中const优先let次之。
3.4数据类型
typeof操作符用来区分函数和其他对象
undefined 和 null 的****区别
undefined 类型表示声明了变量但是未初始化没有值undefined是由null中派生而来的。
null类型表示一个空对象指针。
boolean类型要将一个其他类型的值转换成布尔值可以调用Boolean()转换函数。
let message Hello kuishou;
if(message){console.log(message 已经转换成布尔类型);
}//if等流控制语句会自动执行其他类型转换为布尔类型语句Number类型表示整数和浮点值范围在Number.MIN_VALUE~Number.MAX_VALUE之间。
let Number 68; //整数let octalNum1 070;//八进制56
let octalNum3 08;//无效的八进制数当成8处理let folatNum1 0xA;//十六进制10
let folatNum2 0x1f;//十六进制31let floatNum1 1.1;
let floatNum2 0.1;
let floatNum3 .1;//有效但不推荐let floatNum4 1. //小数点后面没有数字当做1处理
let floatNum5 10.0 //小数点后面是0当成整数处理let floatNum6 3.153e7;//以3.153为系数乘以10的7次幂NaNNot a Number意思’不是数值’,表示本来要返回数值的操作失败了。
isNaN() 函数接收一个任意类型的参数判断这个参数是否‘不是数值’
console.log(isNaN(NaN));//true
console.log(isNaN(10));//false,10是数值
console.log(isNaN(10));//false,可以转换为数组
console.log(isNaN(blue));//true,不可以转换为数值
console.log(isNaN(true));//false,可以转换成数值1let num1 Number(Hello kuishou);//NaN 字符串Hello kushou找不到对应的值的时候会提示NaN
let num2 Number(); //0
let num3 Number(000011); //11
let num4 Number(true); //1数值转换Number、parseInt()、parseFloat()
paresInt() 函数能识别不同的整数格式十进制、八进制、十六进制
let num1 parseInt(1234blue);//1234
let num2 parseInt(); //NaN
let num3 parseInt(0xA); //10,解释为十六进制
let num4 parseInt(22.5); //22
let num5 parseInt(70); //70,解释为十进制let num1 parseInt(10,2); //2,按二进制解析
let num2 parseInt(10,8); //8,按十进制解析
let num3 parseInt(10,10); //10,按十进制解析
let num4 parseInt(10,16); //16按十六进制解析String 类型可以用双引号、单引号、反引号标示。
let Name kuishou;
let Name lingxiu;
let Name jianlin;toSting() 转换为字符串。
let num 10;
console.log(num.toString(2));//1010,转换成二进制数let num kuishou;
console.log(String(num)); //kuishou模板字面量求值后得到的字符串保留换行字符可以跨行定义字符串。
let myMultLineString first line\nsecond line;
let myMultLineTemplatLiteral first line second line;
console.log(myMultLineString); //first line// second line
console.log(myMultLineTemplatLiteral); //first line second line
console,log(myMultLineString myMultLineTemplatLiteral); //true
//模板字面量在定义模板时特别有用比如下面这个 HTML 模板:
let
diva href#spankuishou/span/a
/div字符串插值可以在一个连续定义中插入一个或多个值。
let value 5;
let exponent second;
// 以前的写法
let interpolatedString value to the exponent power is (value * value);
// 现在的写法
let interpolatedTemplateLiteral ${ value } to the ${ exponent } power is ${ value * value };
console.log(interpolatedString); // 5 to the second power is 25
console.log(interpolatedTemplateLiteral); // 5 to the second power is 25
//模板也可以插入自己之前的值
let value ;
function append(){value ${value}abcconsole.log(value);
}
append(); //abc,第一遍显示abc
append(); //abcabc,第二遍在abc前面加了abc
append(); //abcabcabc,第三遍在abcabc前面加个abc模板字面量标签函数通过标签函数自定义插值行为.
let a 8;
let b 9;
function simpleTag(strings,aValExpression,bValExpression,sumExpression){console.log(strings);// [, , , ]console.log(aValExpression);// 6console.log(bValExpression);// 9console.log(sumExpression);// 15return foobar;
}
let untaggedRealut ${a} ${b} ${ab};
let taggedRedult simpleTag${a} ${b} ${ab};
console.log(untaggedResult); // 6 9 15
console.log(taggedResult); // foobar Symbol类型确保对象属性使用使用唯一的标识符不会发生冲突的危险。是用来创建唯一记号进而用作非 字符串形式的对象属性。
let o {[Symbol(fool)]:foo val, [Symbol(bar)]:bar val
}
console.log(o); //{Symbol(fool): foo val, Symbol(bar): bar val}let barSymbol Object.getOwnPropertySymbols(o).find((symbol) symbol.toString().match(/bar/));
console.log(barSymbol); //Symbol(bar)Symbol符号属性Symbol.asyncItertor一个方法该方法返回的对象默认到的AsyncItertor,由for-await-of语句使用。Symbol.hasInstance一个方法该方法决定一个构造器对象是否认可的一个对象是它的实例。Symbol.isConcatSpreadable一个布尔值如果是true,则意味着对象应该用Array.protype.concat()打平其数组元素。Symbol.iterator一个方法该方法返回对象默认的迭代器由for-of语句使用Symbol.match一个正则表达式该方法用正则表达式去匹配字符串。Symbol.replace一个正则表达式方法该方法替换一个字符串中匹配的字符Symbol.search一个正则表达式方法该方法返回字符串中匹配正则表达式的索引Symbol.species一个函数值该函数作为创建派生对象的构造函数Symbol.spilt一个正则表达式方法该方法在匹配正则表达式的索引位置拆分字符串。Symbol.toPrimitve一个方法该方法将对象转换为相应的原始值。Symbol.toStringTag一个字符串该字符串用于创建对象的默认字符串描述。Symbol.unscopables一个对象该对象所有的以及继承的属性都会从关联对象的With环境绑定中排除。
Object 类型通过创建 Object 类型的实例来创建自己的对象然后再给对象添加属性和方法。
Object实例属性constructor用于创建当前对象的函数。hasOwnProperty(propertyName)用于判断当前对象实例不是原型上是否存在给定的属性。isPrototypeOf(object)用于判断当前对象是否为另一个对象的原型。propertyIsEnumerable(propertyName)用于判断给定的属性是否可以使用。toLocaleString()返回对象的字符串表示该字符串反映对象所在的本地化执行环境。toString()返回对象的字符串表示。valueOf()返回对象对应的字符串、数值或布尔值表示。
3.5一元操作符只操作一个值的操作符
位操作符有符号整数使用32位前31位表示整数值第32位表示数值的符号这一位称为符号位他的值决定了数值其余部分的格式。
布尔操作符逻辑与短路操作符、逻辑或||、逻辑非!
乘性操作符乘法*、除法/、取模%
指数操作符Math.pow(底数指数)
加性操作符加法、减法-
关系操作符小于、大于~~~
3.6语句
if语句
if(i18){console.log(成年了);
}else if(i22){soncole.log(大学毕业了);
}else{console.log(找工作了);
}do-while语句:后测试语句
let i 0;do{i 2;console.log(i);
}while(i10);whilel语句: 先测试语句
let i 0;
while(i10){i 2;console.log(i);
}for语句:
for(let i 0;i10;i){console.log(i);
}for-in语句for(property in windows ) statment用于枚举对象中的非符号键属性每次循环都给变量property 赋予一个 windows对象的属性作为值直到所有属性都被枚举一遍。
for(const propName in windows){console.log(propName);
}//表示每次执行循环都会给变量propName赋予一个windows对象的属性作为值直到windows的所有属性都被枚举一遍。for-of语句for(const el of [1,3,5,7])用于遍历可迭代对象的元素循环会持续到所有元素都别迭代完。
for(const el of [1,3,5,7,9]){console.log(el);//以此输出1,3,57,9
}for in 和 for of 的区别:
var a [a,b,c,d,e];
for (var idx in a) {//建议 循环对象属性 的时候使用。console.log( idx );
}
// 0 1 2 3 4 for..in 在数组 a 的键 / 索引上循环。
for (var val of a) {//建议 遍历数组 的时候使用console.log( val );
}
// a b c d e 而 for..of 在 a 的 值 上循环。①在底层for…of 循环向 iterable 请求一个迭代器然后反复调用这个迭代器把它产生的值赋给循环迭代变量。—《你不知道的JavaScript-下卷》
②for…of可以通过break、continue、return 提前终止并抛出异常。—《你不知道的JavaScript-下卷》
break 和 continue的区别
break语句跳出当前循环执行循环后的下一条语句
let num 0;
for(let i 1;i10;i){if(i%50){break;}num;
}
console.log(num);//结果是4,为什么//因为循环体递增到i能够被5取模的时候循环体已经跳出了num没有继续1continue语句退出循环后再次回到循环顶部重新开始执行。
let num 0;
for(let i 1;i10;i){if(i%50){console.log(num);continue;}num;console.log(num);
}
console.log(num);//结果是8为什么//因为循环体递增到i能够被5取模的时候遇到continue跳出再次回到循环顶部重新执行了一遍//又因为0%5和1%5都等于1所以最终结果为8。switch语句
switch(i){case 25:console.log(25);borek;case 35:console.log(35);borek;case 45:console.log(45);borek;case 55:console.log(55);borek;default:console.log(Outher);
}With语句用于设置代码在特定对象中的作用域
var sMessage hello kuishou;
with(sMessage){alert(toUpperCase());//
}3.7函数
diff()函数结算两个数值的差。
function diff(num1,num2){//diff()函数用于计算两个数值的差if(num1num2){return num2 - num1;}else{return num1-num2;}
}sayHi()函数合并传递的参数并用逗号隔开。 第4章——变量、作用域与内存
4.1传递参数
function addTen(num){num 10;return num;
}
let count 20;
let result addTen(count);
console.log(count);//20
console.log(result);//30function setName(obj) {obj.name kuishou;obj new Object();obj.name jianlin;
}
let person new Object();
setName(person);
console.log(person.name);//kuishou4.2执行上下文与作用域。
每个上下文都有一个关联的变量对象,这个上下文中定义的所有变量和函数都存在于这个对象上。
var color blue;
function changeColor(){if(color blue){color red;}
}
changeColor(); //这个函数的作用域包含两个对象所以能把red显示在全局变量中
console.log(color);//red4.3垃圾回收 确定某个变量不会再使用然后释放它占用的内存周期性清理属于’不判定的‘问题。 两种标记策略标记清理、引用计数。
标记清理声明一个变量时这个变量就会被加上 **存在于上下文 **的标记垃圾回收程序运行的时候被加上标记的变量就是待删除变量随后垃圾回收程序做一次内存清理销毁带标记的所有值并回收他们的内存。
functiontest(){vara 10 ; //被标记进入环境varb 20 ; //被标记进入环境
}
test();//执行完毕之后 a、b又被标离开环境被回收。引用计数对每个值都记录它被引用的次数变量被引用一次那么引用数1变量被其他值覆盖引用值-1当引用值为0的时候回收其内存。
functiontest(){vara {} ; //a的引用次数为0varb a ; //a的引用次数加1为1varc a; //a的引用次数再加1为2varb {}; //a的引用次数减1为1
}第5章——基本引用类型
5.1 Date 类型
let now new Date();
console.log(now);//Tue Mar 23 2021 18:03:19 GMT0800 (中国标准时间)5.2 RegExp 正则表达式
// g全局模式表示查找字符串的全部内容而不是找到第一个匹配的内容就结束。
// i不区分大小写表示在查找匹配时忽略 pattern 和字符串的大小写。
// m多行模式表示查找到一行文本末尾时会继续查找。
// y粘附模式表示只查找从 lastIndex 开始及之后的字符串。
// uUnicode 模式启用 Unicode 匹配。
// sdotAll 模式表示元字符.匹配任何字符包括\n 或\r。
// 匹配字符串中的所有at
let pattern1 /at/g;
// 匹配第一个bat或cat忽略大小写
let pattern2 /[bc]at/i;
// 匹配所有以at结尾的三字符组合忽略大小写
let pattern3 /.at/gi;
// 匹配第一个bat或cat忽略大小写
let pattern1 /[bc]at/i;
// 匹配第一个[bc]at忽略大小写
let pattern2 /\[bc\]at/i;
// 匹配所有以at结尾的三字符组合忽略大小写
let pattern3 /.at/gi;
// 匹配所有.at忽略大小写5.3 原始值包装类型
Boolean 类型
let falseObject new Boolean(false);
let result falseObject true;
console.log(result);//trueNumber 类型
let num 10;
console.log(num.toString(2));//1010转换成二进制
console.log(num.toFixed(2));//10.00,返回2位小数点位数的数值字符串
console.log(num.toExopnential(1));//1.0e1带0-20个小数位的数值
console.log(num.toString(1));//1.0e2,带1-21个小数位的数值String 类型
let stringValue new String(Hello kuishou);
console.log(stringValue.length);//13,字符串的字符数量为13一个空格占两个字节let stringValue Hello kuishou;
console.log(stringValue.slice(3));//llo kuishou从左边0位开始返回3后面所有的字符串
console.log(stringValue.slice(3,7));//llo从左边0位开始返回3-7这个区间内所有的字符串
console.log(stringValue.slice(-3));//hou,从右边开始返回-3前面面所有的字符串
console.log(stringValue.slice(3,-4));//llo kui从右边开始返回3-7这个区间内所有的字符串console.log(stringValue.indexOf(o))//4,从左边开始找出字母o所在的位置
console.log(stringValue.lastIndexOf(o))//11,从左边开始找出字母o所在的位置
console.log(stringValue.indexOf(o,6));//11,从位置6字符k开始向后开始搜索在位置11找到了o
console.log(stringValue.lastIndexOf(o,6));//4,从位置6字符k开始反向开始搜索在位置4找到了otrim()方法创建字符串的一个副本删除前后所有空格符再返回起结果。
let stringValue hello world ;
let trimmedStringValue stringValue.trim();
console.log(stringValue); // hello world
console.log(trimmedStringValue); // hello world repeat()方法接收一个参数将字符串复制参数中指定的次数然后拼接所有副本的结果。
let stringValue na ;
console.log(stringValue.repeat(16) batman);
// na na na na na na na na na na na na na na na na batman5.4 Math
let max new Math.max(1,2,3,4,5);
console.log(max);//let min new Math.min(1,2,3,4,5);
console.log(min);**Math.round()**方法执行四舍五入
Math.ceil()方法始终向上舍入最接近的整数。
Math.floor()方法始终向下舍入最接近的整数。
Math.round()方法执行四舍五入。
Math.fround()方法返回数值最接近的单精度32位浮点值表示。
console.log(Math.ceil(25.9));//26,向上取整
console.log(Math.ceil(25.5));//26
console.log(Math.ceil(25.4));//26
console.log(Math.ceil(25.1));//26console.log(Math.floor(25.9));//25向下取整
console.log(Math.floor(25.5));//25
console.log(Math.floor(25.4));//25
console.log(Math.floor(25.1));//25console.log(Math.round(25.9));//26四舍五入
console.log(Math.round(25.5));//26
console.log(Math.round(25.4));//25
console.log(Math.round(25.1));//25console.log(Math.fround(25.9));//25.899999618530273返回数值最接近的单精度浮点值
console.log(Math.fround(25.5));//25.5
console.log(Math.fround(25.4));//25.399999618530273
console.log(Math.fround(25.1));//25.100000381469727**Math.random()**生成随机数。
let num Math.floor(Math.random()*101);
console.log(num);//1~10范围内的随机数/*-------------------------- */
function selectFrom(lowerValue,upperValue){let choices upperValue - lowerValue 1;return Math.floor(Math.random() * choices lowerValue);
}
let num selectFrom(2,10);
console.log(num); //2~10范围内的随机数/*-------------------------- */
let colors [red,green,blue,black,brown];
let color [selectFrom(0,colors.length-1)];
console.log(color);第6章——集合应用类型
6.1 Object
object适合存储和在应用程序之间交换数据。
对象字面量对象定义的简写形式目的是为了简化包含大量属性的对象的创建。
let person {//对象字面量 表示法name : kuishou,age : 21,sex : 男
};function displayInfo(args){let output ;if(typeof args.name string){output Name: args.name \n;}if(typeof args.age number){output Age: args.age \n;}alert(output);//Name:kuishou Age:21
}displayInfo({name: kuishou,age: 21
});displayInfo({name: lingxiu
});6.2 Array 数组 创建数组
let colors new Array();
let colors new Array(red,blue,black);
let colors [red,green,black];//Array.from()拆分、合并数组
console.log(Array.from(kuishou));//[k, u, i, s, h, o, u],拆分数组const s new Set().add(1).add(2).add(3).add(5).add(4);
console.log(Array.from(s));//[1, 2, 3, 5, 4]合并数组const m new Map().set(1,2).set(3,4);
console.log(Array.from(m));//[[1,2],[3,4]]合并二维数组//Array.of()把一组参数转换为数组
console.log(Array.of(1,2,3,4,5));//[1, 2, 3, 4, 5]
console.log(Array.of(red,black,green));//[red, black,green]//数组索引let colors [red,yellow,blue];console.log(colors[0]); //red显示第一项colors[2] yellow;//修改第三项中bluecolors[3] green; //添加第四项数组长度1console.log(colors.length);//4,显示数组长度迭代器方法keys()返回数组索引,values()返回数组元素entries()返回索引/值对。
const b [red,blue,green,black];//注意const在控制台声明时候会被初始化变量也就是这个变量用过一次之后不能再重复使用了。
const bKeys Array.from(b.keys());
console.log(bKeys); //[0, 1, 2, 3]
const bValues Array.from(b.values());
console.log(bValues); // [red, blue, green, black]
const bEntries Array.from(b.entries());
console.log(bEntries); // [[0, red],[1, blue],[2, green],[3, black]]栈方法posh()推入pop()弹出遵循后进先出的原则。
let colors [red,green];
let count colors.push(blue,black);//推入两项
console.log(count); //4,push接收参数后返回数组最新长度let item colors.pop(); //弹出最后一项
console.log(item); //black队列方法shift()删除数组中第一项并返回数组长度posh()在数组末尾添加数据遵循先进先出原则。
let colors [red,green];
let count colors.push(blue,black);//推入两项
console.log(count); //4,push接收参数后返回数组最新长度let item colors.shift(); //取得第一项
console.log(item); //red排序方法reverse()反向排序sort()中包含一个比较函数用于判断那个值应该排在前面。
let values [1,2,3,4,5]
let count values.reverse();
console.log(count); //[5, 4, 3, 2, 1]降序
console.log(count.sort()); //[1, 2, 3, 4, 5]升序function compare(value1,value2){//降序if(value1 value2){return 1;}else if(value1 value2){return -1;}else{return 0;}
}
let values [0,1,5,10,15,20];
console.log(values.sort(compare));//[20, 15, 10, 5, 1, 0]function compare(value1,value2){//升序if(value1 value2){return -1;}else if(value1 value2){return 1;}else{return 0;}
}
let values [20, 15, 10, 5, 1, 0];
console.log(values.sort(compare));//[0, 1, 5, 10, 15, 20]操作方法concat()在现有数组后面创建一个新的数组;slice()创建一个包含原有数组中一个或多个元素的心数组splice()在数组中插入新的元素删除传递2个参数第一个是元素的位置第二个是删除的数量插入传递3个参数
//concat()可以在现有数组的基础上创建一个新数组
let colors [red,green,blue];
let colors2 colors.concat(yellow,[black,brown]);//传入yellow和数组[black,brown]默认不打平
console.log(colors); // [red, green, blue]
console.log(colors2); //[red, green, blue, yellow, black, brown]形成一个新数组let colors [red,blue,green];
let newColors [black,brown];
let moreNewColors {[Symbol.isConcatSpreadable] : true,length : 2,0 : pink,1 : cyan
};
newColors[Symbol.isConcatSpreadable] false;
//强制不打平数组
let colors2 colors.concat(yellow,newColors);
//强制打平数组
let colors3 colors.concat(moreNewColors);
console.log(colors); //[red, blue, green]
console.log(colors2); //[red, blue, green, yellow, [black,brown]],不打平数组输出二维数组
console.log(colors3); //[red, blue, green, pink, cyan]打平数组强制输出一维数组//slicie()用于创建一个包含原有数组中一个或多个元素的新数组
let colors [red,green,blue,black,pink];
let colors2 colors.slice(1); //从索引1(green)开始读取1后面所有值
console.log(colors2); //[green, blue, black, pink]
let colors3 colors.slice(1,4); //从索引1(green)开始3(black)结束读取区间内的值
console.log(colors3); //[green, blue, black]let colors [red,green,blue];
let removed colors.splice(0,1); //删除第一行
console.log(colors); //[green, blue]removed colors.splice(1,0,yellow,orange); //在位置1插入两个元素
console.log(colors); //[green, yellow, orange, blue]removed colors.splice(1,1,red,peuple); //插入两个值删除一个元素
console.log(colors) //[green, red, peuple, orange, blue]迭代方法三个参数数组元素、元素索引、数组本身,
* every()从数组中搜索符合某个条件的元素传入的函数对每一项都返回true这个方法才会返回true.
* some()从数组中搜索符合某个条件的元素传入的函数只要有一项返回true这个方法就返回true.
* filter()满足条件的项组成新的数组返回。
* map()返回的结果组成新的数组。
* forEach()会运行每一项传入的函数没有返回值实现遍历。
let numbers [1,2,3,4,5,4,3,2,1];
let everyResult numbers.every((item,index,array) item 2);
console.log(everyResult);//falselet someResult numbers.some((item,index,array) item 2);
console.log(someResult);//truelet filterResult numbers.filter((item,index,array) item 2);
console.log(filterResult);//[3, 4, 5, 4, 3]let mapResult numbers.map((item,index,array) item * 2);
console.log(mapResult);//[2, 4, 6, 8, 10, 8, 6, 4, 2]归并方法接收四个参数上一个归并值、当前项、当前项的索引、数组本身。
* reduce()从第一项开始遍历到最后一项
* reduceRight()从最后一项遍历到第一项
let values [1,2,3,4,5];
let sum values.reduce((prev,cur,index,array) prev cur);
console.log(sum);//15,从左至右归并第一次执行prev是1cur是2第二次执行prev是3cur是3第三次执行prev是6cur是4依次归并最后sum为15let sum values.reduceRight(function(prev,cur,index,array){return prev cur;
});
console.log(sum);//15从右边向左边归并。6.4 Map
Map是一种新的集合类型使用对象属性作为键再使用属性来引用值。
* get()、set()查询
* size()获取映射中的数量
* delete()、clear()删除
const m1 new Map([//使用嵌套数组初始化映射[key1,val1],[key2,val2],[key3,val3],
]);
console.log(m1.size);const m new Map();m.set(firstName,Matt).set(lastName,Frisbie);
console.log(m.has(firstName));//true
console.log(m.get(firstName));//Math
console.log(m.size);//2m.delete(firstName);//只删除这一个键/值对
console.log(m.has(firstName));//false
console.log(m.get(lastName));//Frisbie,get获取的lastName键返回得到是Frisbie值
console.log(m.size);//1,删除之后长度-1m.clear(firstName);//清除这个映射实例中的所有键/值对
console.log(m.has(firstName));//false
console.log(m.get(lastName));//undefined
console.log(m.size);Map和Object的区别
内存方面Map比Object多存储50%的键/值对
插入性能插入速度不会随着键/值对的数量增加而线性增加
查找速度Object当做数组使用的情况下Object速度更佳
删除性能Map 的 delete()操作都比插入和查找更快。 第7章——迭代器与生成器
迭代器是一个对象它定义了一个序列并在终止时返回值。两个返回值value、done。可以由任意对象实现的接口支持连续获取对象产出的每一个值。
for (let i 1;i 10;i){console.log(i);
}//1 2 3 4 5 6 7 8 9 10let collection [foo,bar,baz];
for(let index 0;index collection.length;index){console.log(collection[index]);
}//foo bar bazcollection.forEach((item) console.log(item));//foo bar baz可迭代协议支持自我识别能力和创建实现Iterator接口对象的能力。
//for-of 循环
let arr [foo,bar,baz];
for(let el of arr){console.log(el);//foo bar baz
}//数组解构
let arr [foo,bar,baz];
let [a,b,c] arr;
console.log(a,b,c);//foo bar baz//扩展操作符
let arr [foo,bar,baz];
let arr2 [...arr];
console.log(arr2);//[foo, bar, baz]//Array.from()
let arr [foo,bar,baz];
let arr3 Array.from(arr);
console.log(arr3);//[foo, bar, baz]//Set构造函数
let arr [foo,bar,baz];
let set new Set(arr);
console.log(arr);//[foo, bar, baz]//Map构造函数
let arr [foo,bar,baz];
let pairs arr.map((x,i) [x,i]);
console.log(pairs);//[[foo, 0], [bar, 1], [baz, 2]]let map new Map(pairs);
console.log(map);// {foo 0, bar 1, baz 2}迭代对象一种一次性使用的对象用于迭代与其关联的可迭代对象。
//可迭代对象
let arr [foo,bar];
//迭代器工厂函数
console.log(arr[Symbol.iterator]);//values() { [native code] }
//迭代器
let iter arr[Symbol.iterator]();
console.log(iter);//Array Iterator {}
//执行迭代
console.log(iter.next());//{value: foo, done: false}
console.log(iter.next());//{value: bar, done: false}
console.log(iter.next());//{value: undefined, done: true}生成器允许定义一个包含自由迭代算法的函数同时它可以自动维护自己的状态拥有一个函数块内暂停和恢复代码执行的能力生成器的形式是一个函数函数名称前面加一个星号*表示它是一个生成器。
//生成器函数声明
function* generationFn(){}
//生成器函数表达式
let generationFn function* (){}
//作为对象字面量方法的生成器函数
let foo {* generationFn(){}
}
//作为类实例方法的生成器函数
class Foo{* generationFn(){}
}
//作为类静态方法的生成器函数
class Bar{static* generationFn(){}
}
//生成器放回指定的值
function* generationFn(){return foo;
}
let generatorObject generationFn();
console.log(generatorObject);//generationFn {suspended}
console.log(generatorObject.next());//{value: foo, done: true}/*** yield中断执行*/
function* generationFn(){yield foo;yield bar;return baz;
}
let generatorObject generationFn();
console.log(generatorObject.next());//{value: foo, done: false}
console.log(generatorObject.next());//{value: bar, done: false}
console.log(generatorObject.next());//{value: baz, done: true}第8章——对象、类与面向对象编程
8.1 理解对象
面向字面量书写方式
let person {name: kuishou ,age:21,job:前端开发,sayName(){console.log(this.name);}
};8.1.1 定义多个属性
Object.defineProperties()通过多个描述符一次性定义多个属性。
let book {};
Object.defineProperty(book,{year_:{value:2021},edition:{value:1},year:{get(){return this.year_;},set(newValue){if(newValue 2020){this.year_ newValue;this.edition newValue - 2020;}}}
});8.1.2 读取属性的特征
Object.getOwnProprttyDescriptor()可以指定属性的特征描述符
let book {};
Object.defineProperties(book,{year_:{value:2021},edition:{value:1},year:{get:function(){return this.year_;},set:function(newValue){if(newValue 2020){this.year_ newValue;this.edition newValue - 2020;}}}
})
let descriptor Object.getOwnPropertyDescriptor(book,year_);
console.log(descriptor.value); //2021
console.log(descriptor.configurable); //false
console.log(descriptor.enumerable); //undefined
console.log(typeof descriptor.get); //undefined8.1.3 合并对象把源对象所有的本地属性一起复制到目标对象上。
Object.assign()对每个源对象执行的是浅复制。
let dest , src , result;
//覆盖属性
dest {id: dest};
result Object.assign(dest,{id:src1,a:foo},{id:src2,b:bar});
console.log(result);//{id: src2, a: foo, b: bar}/*** 属性值简写*/
let name Matt;
let person {name
};
console.log(person);//{name: Matt}/*** 对象解构*/
let person {name:Matt,age:21
};
let {name:personName,age:personAge} person;
console.log(personName);//Matt
console.log(personAge);//218.2 创建对象 8.2.1 工厂模式用于抽象特定对象的过程。
function createPerson(name,age,job){let o new Object();o.name name;o.age age;o.job job;o.sayName function(){console.log(this.name);};return o;
}
let person1 createPerson(kuishou,21,前端开发);
let person2 createPerson(lingxiu,20,后端开发);8.2.1 构造函数模式用于创建特定类型对象。
function Person(name,age,job){this.name name;this.age age;this.job job;this.sayName function(){console.log(this.name);};
}
let person1 createPerson(kuishou,21,前端开发);
let person2 createPerson(lingxiu,20,后端开发);
person1.sayName();//kuishou
person2.sayName();//lingxiu8.3 继承
function SuperType(){this.property true;
}
SuperType.prototype.getSuperValue function(){return this.property;
}
function SubType(){this.subproperty false;
}
//继承SuperType
SubType.prototype new SuperType();
SubType.prototype.getSuperValue function(){return this.subproperty;
};
let instance new SubType();
console.log(instance.getSuperValue());8.4 类
定义类的两种方式
// 类声明
class Person {}
// 类表达式
const Animal class {}; 函数声明可以提升类的定义不能。
类的构造函数 不定义构造函数相当于将构造函数定义为空函数。
继承不仅可以继承一个类也可以继承普通的构造函数。
抽象基类可供其他类继承当本身不会被实例化使用new,target检测是不是抽象基类. 第9章——代理与反射
9.1 代理
拦截并向基本操作嵌入额外行为的能力target目标对象handler代理对象Reflect也可以
const target {id: target
};
const handler {};
const proxy new Proxy(target, handler);
// id 属性会访问同一个值
console.log(target.id); // target
console.log(proxy.id); // target
// 给目标属性赋值会反映在两个对象上
// 因为两个对象访问的是同一个值
target.id foo;
console.log(target.id); // foo
console.log(proxy.id); // foo
// 给代理属性赋值会反映在两个对象上
// 因为这个赋值会转移到目标对象
proxy.id bar;
console.log(target.id); // bar
console.log(proxy.id); // bar
// hasOwnProperty()方法在两个地方
// 都会应用到目标对象
console.log(target.hasOwnProperty(id)); // true
console.log(proxy.hasOwnProperty(id)); // true
// Proxy.prototype 是 undefined
// 因此不能使用 instanceof 操作符
console.log(target instanceof Proxy); // TypeError: Function has non-object prototype
undefined in instanceof check
console.log(proxy instanceof Proxy); // TypeError: Function has non-object prototype
undefined in instanceof check
// 严格相等可以用来区分代理和目标
console.log(target proxy); // false第10章——函数
10.1 箭头函数
let arrowSum (a,b) {//箭头函数return ab;
};
let functionExpressionSum function (a,b) {//普通函数return ab;
}
console.log(arrowSum(6,8));//14
console.log(functionExpressionSum(6,8));//1410.2 函数内部
arguments对象是一个类数组对象第一个参数是arguments[0],第二个参数是arguments[1])。
function doAdd(){if(arguments.length1){console.log(arguments[0]10);}else if(arguments.length2){console.log(arguments[0]arguments[1]);}
}
doAdd(10);//20
doAdd(20,30);//50let trueFactorial factorial;
factorial function(){return 0;
};
console.log(trueFactorial(5));//120
console.log(factorial(5));//0this 对象在标准函数中this引用的是把函数当成方法调用的上下文对象。
window.coloe red;
let o {color:bule
};
function sayColor(){console.log(this.coolor);
}
sayColor();//redo.sayColor sayColor;
o.sayColor();//blue//this 在箭头函数中this引用的是定义箭头函数的上下文。
windows.color red;
let o {color:blue
};
let sayColor () console.log(this.color);
sayColor();//red
o.sayColor sayColor;
o.sayColor();//red10.3 递归 一个函数通过名称自己调用自己。
arguments.callee 指向一个正在执行的函数的指针。
function factorial(num){if(num1){return 1;} else {return num*arguments.callee(num-1);}
}const factorial (function f(num){if (num1){return 1;} else {return num*f(num-1);}
});
10.4 闭包引用了另一个函数作用域中变量的函数通常是在嵌套函数中实现的。本质是包含函数的活动对象加长了其作用域链。
function createComparisonFunction(propertyName){return function(object1,object2){let value1 object1[propertyName];let value2 object2[propertyName];if(value1 value2){return -1;} else if(value1 value2){return 1;}else{return 0;}};
}10.5 模块模式通过自定义类型创建了私有变量和特权方法。
let singleton {name:value,method(){//方法的代码}
};let singleton function(){//私有变量和私有函数let privateVariable 10;function privateFunction(){return false;}//特权、公有方法和属性return {publicProperty: true,publicMethod(){privateVariable ;return privateFunction}}
}第11章——期约与异步函数
11.2 期约promise:是对 尚不存在结果 的一个替身。
/*** 期约与异步函数* 什么是Promise?* 1从语法上来说Promise是一个构造函数* 2从功能上来说Promise对象用来封装一个异步操作并获取其结果。* Promise基本远行流程* 1创建一个新的Promise 对象* 2) 执行异步操作任务* 3异步任务成功则返回resolve(),失败则返回reject()* 4resolved状态通过then()回调onResolved();rejected状态通过then()/catch()回调onReject()* 5最后形成一个新的Promise对象*/
//失败处理
function double(value,success,failure){setTimeout(() {try{if(typeof value ! number){throw Must provide number as firdt argument;}success(2 * value);}catch(e){failure(e);}},1000);
}const successCallback (x) console.log(Success${x});
const failureCallback (e) console.log(Failure${e});double(3,successCallback,factorialCallack);
double(b,successCallback,factorialCallack);//嵌套异步回调
function double(value,success,failure){setTimeout(() {try{if(typeof value ! number){throw Must provide number as firdt argument;}success(2 * value);}catch(e){failure(e);}},1000)
}const successCallback (x) {double(x,(y) console.log(Success${y}));
};
const failureCallback (e) console.log(Failure:${e});
double(3,successCallback,failureCallback);
Promise 对象状态改变的方式
//1.声明一个Promise对象的状态
let p new Promise((resolve,reject) {//resolve 函数resolve(OK);//pending fulfilled(resolve)//reject 函数reject(Error);//pending rejected//抛出错误throw 出问题了;
});
console.log();//Promise指定多个成功/失败回调函数都会调用嘛
//当Promise改变为对应状态时都会被调用
let p new Promise((resolve,reject) {resolve(OK);
});
//指定回调
p.then(value {console.log(value);
});
//指定回调
p.then(value {alert(value);
});三种状态待定pending、兑现(resovle)、拒绝(reject)
/*** promise 期约是对尚不存在结果的一个替身* 三种状态待定pending、兑现fulfilled,可以叫解决resolve、拒绝rejected三种状态不可逆* 待定pending:期约的最初始状态。* 兑现fulfilled:期约落定settled为代表成功状态* 拒绝rejected:期约落定settled为代表失败状态* 用途抽象的表示一个异步操作状态代表期约是否完成。*/
let p new Promise(() {});
setTimeout(console.log,0,p);let p1 new Promise((resolve,reject) resolve());
setTimeout(console.log, 0 ,p1)//Promise {fulfilled: undefined}let p2 new Promise((resolve,reject) reject());
setTimeout(console.log, 0 ,p2)//Promise {rejected: undefined}Promise.prototype.then()为Promise实例添加状态改变时的回调函数。
//then方法返回的是一个新的Promise实例。
getJSON(/post/1.json).then(post getJSON(post.commentURL)
).then(comments console.log(resolved:,comments),err console.log(rejected:,err)
);Promise.prototype.catch() 发生错误时的回调函数。
const somrAsyncThing function(){return new Promise(function(resolve,reject){resolve(x 2);//会报错因为x没有声明});
};
somrAsyncThing().catch(function(error){console.log(error,error);
}).then(function(){console.log(error);
});Promise.prototype.finally() 不管Promise对象最后状态如何都会执行的操作。
let p1 Promise.resolve();
let p2 Promise.reject();
let onFinally function(){setTimeout(console.log, 0, Finally!)
}
p1.finally(onFinally);//Finally
p2.finally(onFinally);//FinallyPromise.all() 接收一个可迭代对象返回一个新期约在一组期约全部解决之后再解决。
const p1 new Promise((resolve,reject) {resolve(hello);
}).then(result result);const p2 new Promise((resolve,reject) {throw new Error(error);
}).then(result result);Promise.all([p1,p2])
.then(result console.log(result))
.catch(e console.log(e));Promise.race() 将多个Promise实例包装成一个新的Promise实例。
const p Promise.race([p1,p2,p3]);//只要有一个实例率先改变状态P的转态就会发生改变
const p Promise.race([fetch(/resource-that-may-take-a-while),new Promise(function(resolve,reject){setTimeout(() reject(new Error(request timeout)),5000)})
]);
p.then(console.log).catch(console.error);11.3 异步函数旨在解决利用异步结构 组织代码的问题
async关键字用于声明异步函数它是Generator 函数的语法糖。
async function foo(){}
let bar async function(){};
let baz async () {};
class Qux{async qux(){}
}let p new Promise((result,reject) setTimeout(result,1000,3));
p.then((x) console.log(x));//3await关键字用于暂停步函数代码的执行等待期约解决。
async function foo(){let p new Promise((resolve,reject) setTimeout(resolve,1000,3));console.log(await p);
}
foo();//3//停止和恢复执行
async function foo(){console.log(2);await null;console.log(4);
}
console.log(1);
foo();
console.log(3);
//1
//2,打印完2后由于遇到arait关键字null向消息队列添加一个任务退出foo()
//3.打印完3再次回到foo()中恢复执行。
//4async function foo(){console.log(2);console.log(await Promise.resolve(8));console.log(9);
}
async function bar(){console.log(4);console.log(await 6);console.log(7);
}
console.log(1);
foo();
console.log(3);
bar();
console.log(5);手写Promise :
// 参见的内置错误
// 1).ReferenceError:引用的变量不存在
console.log(a); //Uncaught ReferenceError: a is not defined// 2).TypeError:数据类型不正确
b {}
b.xxx()//VM274:2 Uncaught TypeError: b.xxx is not a function//3).RangeError:数据值不在其所允许的范围内
function fn(){fn()
}
fn()//ncaught RangeError: Maximum call stack size exceeded//4).SyntaxError语法错误
const c //创建一个Promise对象
const p new Promise((resolve, reject) {setTimeout(() {const time Date.now();if(time % 2 0){resolve(成功的数据timetime);}else{reject(失败的数据timetime);}}, 1000);
})
p.then(value {console.log(成功的回调value);},reason {console.log(失败的回调timereason);}
)//Promise对象用来封装一个异步操作并返回其结果
new Promise((resolve, reject) {setTimeout(() {resolve(成功的数据)reject(失败的数据)//这一部分将不起作用promise每次调用只返回一种结果},1000)
})//Promise.then()
new Promise((resolve, reject) {setTimeout(() {resolve(成功的数据)},1000)
}).then(value {console.log(onResolved()1,value)//onResolved()1 成功的数据}
).catch(reason {console.log(onReject()1,reason)}
)/*** 语法糖用起来很甜方便的传值方式*/
//Promise.resolve()
//产生一个成功值为1的promise的值
const p1 new Promise((resolve, reject) {resolve(1)
})
const p2 Promise.resolve(2);//语法糖
const p3 Promise.reject(3);//语法糖
p1.then(value {console.log(value)});
p2.then(value {console.log(value)});
p3.catch(reason {console.log(reason)});//Promsie.all()都为resolve才算成功,否则返回reject
const p1 new Promise((resolve, reject) {resolve(1)
})
const p2 Promise.resolve(2);//语法糖
const p3 Promise.reject(3);//语法糖const pAll Promise.all([p1,p2,p3])//其中3是一个失败的结果
pAll.then(values {console.log(all onReasoned(),values);},reason {console.log(all onRejected(),reason);//all onRejected() 3}
)//Promise.race()只要有一个resolve/reject就返回其结果
//如果在异步情况下p1,p2,p3谁先到就去谁的结果
const p1 new Promise((resolve, reject) {resolve(1)
})
const p2 Promise.resolve(2);
const p3 Promise.reject(3);const pRace Promise.race([p1,p2,p3])
pRace.then(value {console.log(race onResolve(),value)},reason {console.log(race onRejected(),reason)}
)/*** Promise.then()返回的promise的结果由什么所决定* 1简单表达由then() 指定的回调函数 执行的结果 决定* 2详细表达* ①如果抛出异常新promise变为reject,reason为抛出的异常。* ②如果返回的是非promise的值新promise变为resolved,value为返回的值* ③如果返回的是另一个新的promise,次promise的结果就会编程新promise的结果*/
new Promise((resolve, reject) {resolve(1);//onResolved1() 1 onResolved2() undefined// reject(1);//onRejected1() 1 onResolved2() undefined
}).then(value {console.log(onResolved1(),value);return 2// return Promise.resolve(3)// return Promise.reject(4)// throw 5},reason {console.log(onRejected1(),reason);}
).then(value {console.log(onResolved2(),value);},reason {console.log(onRejected2(),reason);}
)/*** Promise如何串联多个操作任务* 1promise的then()返回的一个新的promise,可以开成then()的链式调用。* 2通过then的链式调用串连多个同步/异步任务*/
new Promise ((resolve, reject) {setTimeout(() {console.log(执行任务1异步);resolve(1)},1000);
}).then(value {console.log(执行任务2的结果,value);console.log(执行任务2同步);return 2;}
).then(value {console.log(执行任务3的结果,value)}
)/*** promise异常穿透* (1)当使用promise的then链式调用时可以在最后 指定失败的回调。* (2)前面任何操作做出了异常都会传到最后失败的回调处理。* 中断promise链* (1)当使用promise的then链式调用时在中间中断不再调用后面的回调函数* (2)办法在回调函数中返回一个pending状态的promise对象*/new Promise ((resolve, reject) {resolve(1)
}).then(value {console.log(onRsolved1(),value);}
).then(value {console.log(onRsolved2(),value)}
).then(value {console.log(onRsolved3(),value)}
).catch(reason {console.log(onReasoned4(),reason)}
)宏任务跟微任务 /*** 1.JS中用来存储执行回调函数的队列包含2个不同特定的队列* 2.宏队列用来保存待执行的宏任务回调比如dom事件回调、Ajax回调、定时器setTime回调* 3.微嘟列用来保存待执行的微任务回调比如promise回调、MutaionOberver回调* 4.JS执行时会区别这2个队列、* (1).JS引擎首先必须先执行所有的初始化同步任务代码。* (2).每次准备取出第一个宏任务执行前都要讲所有的微任务一个个取出来执行。*/setTimeout(() {//宏任务 3console.log(callback1())Promise.resolve(3).then(//微任务 4value {console.log(onResolve3(),value)})},0)setTimeout(() {//宏任务 5console.log(callback2())},0)Promise.resolve(1).then(//微任务 1value {console.log(onResolve1(),value)})Promise.resolve(2).then(//微任务 2value {console.log(onResolve2(),value)})//onResolve1() 1//onResolve2() 2//callback()//onResolve3() 3//callback()setTimeout(() {console.log(1)},0)new Promise((resolve) {console.log(2)resolve()}).then(() {console.log(3)}).then(() {console.log(4)})console.log(5)//2 5 3 4 1async 函数和await 函数 /*** 1.async 函数* 函数的返回值为promise对象。* promise对象的结果由async函数执行的返回值决定。* 2.await 表达式* await 右侧的表达式一般为promise对象但也可以是其他的值* 如果表达式是promsie对象await返回的是promise成功的值* 如果表达式是其他值直接将此值作为await的返回值。* */async function fn1(){return 1// throw 2// return Promise.reject(3)}const result fn1()result.then(value {console.log(onResolved,value);//onResolved 1},reason {console.log(onRejected,reason)})function fn2(){return new Promise((resolve, reject) {setTimeout(() {reject(6)},1000)})}function fn4(){return 6;}async function fn3(){const vlaue await fn2();console.log(value,value)}fn3()第12章——BOM
12.1 Windwos对象
BOM 的核心是windows对象windows对象有两个身份另一个是ECMAScript中的Global对象另一个是浏览器窗口的JavaScript接口。
BOM和DOM的区别:
① DOM文档对象模型描述了处理网页内容的方法和接口(windows.document)。
② BOM浏览器对象模型描述了与浏览器进行交互的方法和接口(navigater、history、screen、location、windows)。 第13章——客户端检测
能力检测检测浏览器是否含有某种特性用户代理检测通过用户代理字符串确定浏览器。 第14章——DOM
DOM表示由多层节点构成的文档DOM树。
Element Traversal API 五个属性
childElementCount返回元素数量不包含文本节点和注释。
firstElementChild指向第一个Element类型的子元素。
lastElementChild指向最后一个Element类型的子元素。
previousElementSibling,指向前一个Element类型的同胞元素。
nextElementSibling,指向后一个Element类型的同胞元素。 第15章——DOM拓展 15.1 Selectors API querySelector()返回匹配该模式的第一个后代元素如果没有匹配项则返回结果null。 /*** DOM编程*/
var script document.createElement(script);
var code function sayHi(){alert(h1);};
try{script.appendChild(document.createTextNode(code));
}catch(ex){script.text code;
}
document.body.appendChild(script);//scriptdode/script//querySelector()接收CSS选择符参数返回匹配该模式的第一个后代元素。
let myDiv document.querySelector(#myDiv);//querySelect()接收CSS选择符参数返回所有匹配的节点。
let ems document.querySelectorAll(p strong);//取得所有是p元素子元素的strong元素//DOM对象转Jquery对象
var box document.getElementsByClassName(.box);
var jq $(box);//获取所有div的第0个位置的div
var domeObject $(div)[0];//Jquery对象转换成DOM对象
myvideo.play();//直接调用第17章——事件
17.1 事件流页面接收事件的顺序。事件传播的三个阶段①事件捕获阶段事件是从Document节点自上而下向目标节点传播。②目标阶段达到事件对象的事件目标找到目标节点后完成后停止。③事件冒泡阶段事件再从目标节点自下而上向Document节点传播。 第20章——Streams API 20.2 跨上下文消息一种执行在不同上下文间传递消息的能力。核心是postMessage()方法。 postMessage()方法接收三个参数消息data、文档源origin、文档中的windows对象代理souce。 let iframeWindow document.getElementById(myframe).contentWindow;
iframeWindow.postMessage(A secret,http://www.xxxx.com);//指定源www.xxx.com,x向内嵌窗格发送一条消息Streams API 可读流通过公共接口读取数据块的流由消费者进行处理使用getReader()方法获取流的锁 async function* ints(){//每1000毫秒生产一个递增的整数for(let i 0;i5;i){yieled await new Promise((resovle) setTimeout(resovle,1000,i));}
}
const resdableStream new ReadableStream({async start(controller){for await (let chuck of ints()){controller.enqueue(chunk);}controller.close}
})可写流通过公共接口写入数据块的流生产者将数据写入流。 转换流包含可读流和可写流可根据需要检查和修改流内容。 20.11 Web组件 一套用于增强DOM行为的工具包括影子DOM、自定义元素和HTML模板。 影子DOM通过attachShadow()方法创建并添加给有效HTML元素。
/*** 读取拖放元素*/
let droptarget document.getElementById(droptarget);
function handleEvent(event){let info ,output document.getElementById(output);Files, i,len;event.preventDefault();if(event.type drop){file event.dataTransfer.failes;i 0;len failes.length;while(ilen){info ${files[i].name} (${files[i].type},${files[i].size} bytes)br;i;}output.innerHTML info;}
}
droptarget.addEventListener(dragenter,handleEvent);
droptarget.addEventListener(dragover,handleEvent);
droptarget.addEventListener(drop,handleEvent);//链式调用
function person(){
}person.prototype.getNamefunction(name){this.name name;return this;
}
person.prototype.getAgefunction(age){this.age age;return this;
}
const a new person().getName(kuishou).getAge(21)
console.log(a);第23章——解析与序列化
23.2 JSON对象序列化stringify()方法第一个参数是过滤器可以是数组或函数第二个参数用于缩进结果JSON字符串的选项。解析parse()方法又叫复活函数包含两个参数属性名key和属性值value。可以接收一个额外的参数这个函数会正对每个键/值对都调用一次。 第24章——网络请求与远程资源
GET请求用于向服务器查询某些信息。POSE请求哟用于向服务器发送应该保存的信息。Fetch API 浏览器会向给定的URL发送请求读取响应、处理状态码Web Socket套接字通过一个长时连接实现与服务器全双工、双向的通信。在JavaScript创建Web Socket的时候一个HTTP请求会发送到服务器以初始化连接服务器响应后连接使用的Upgrade头部从HTTP切换到Web Socket协议使用该协议的专有服务器。 第26章——模块
本质上是键/值实体ES6模块默认在严格模式下执行不共享全局命名空间。 第27章——工作者线程 JavaScript是单线程的为了为了解决并发问题JavaScript提出了工作者线程的三种类型 专用工作者线程让脚本单独创建一个JavaScript线程以执行委托的任务。 共享工作者线程创建到的线程可以别多个不同的上下文使用包括不同的页面。 服务工作者线程拦截、重定向和修改页面发出的请求充当王阔请求仲裁者的角色。 充当王阔请求仲裁者的角色。