当前位置: 首页 > Web前端 > JavaScript

JavaScript高级编程笔记03语言基础

时间:2023-03-27 13:30:02 JavaScript

主要基于ES6。一切都区分大小写。无论是变量名、函数名还是运算符标识符,变量名、函数名、属性名、参数名都可以由一个或多个字符组成:第一个必须是字母、_或$;其余可以是字母、_、$或数字。这些字母可以是扩展ASCII中的字母,也可以是Unicode字母字符,例如à和?(但不推荐)。约定使用小驼峰命名法(与内置函数和对象的命名方式一致)。添加了严格模式ES5。为不安全的活动抛出错误Openingmethod:"usestrict";预处理指令保留字、关键字关键字:有特殊用途,不能用作标识符或属性名,最好不要使用,考虑到兼容性)变量var声明的默认值在未初始化时是undefined。scope:函数作用域变量提升全局声明会成为window对象的一个??属性,可以重复声明(提升top后合为一个声明)let声明作用域:块作用域临时死区(let声明前不能引用)global不会成为window对象的属性(仍然会在页面的生命周期中持续存在)同一个块作用域内不允许重复声明(JavaScript引擎会记录用于变量声明的标识符及其块作用域)。申报前,不可能100%确定之前没申报过(假设没申报过);不能用try/catch捕获,也不能用if语句判断,因为会限制for循环中let声明(无条件声明)的范围let声明:迭代变量的范围被限制在里面for循环块。JavaScript引擎会在后台为每个迭代循环声明一个新的迭代变量。const声明行为与let基本相同,唯一的区别是变量必须同时初始化,以后不能修改。限制仅对其指向的变量的引用。如果修改引用内部的属性,则不违反const限制。可以使用静态代码分析工具提前检测非法赋值操作。for..of/for..in循环:每次迭代只创建一个新变量。lessvar,constfirst,letseconddatatype6种简单数据类型(原始类型):undefined,null,boolean,number,string,symbol。1复杂数据类型:object(无序键值对的集合)判断基本类型-typeof:运算符,不是函数"undefined":valueundefined,variableundeclared"boolean""string""number""object":object(non-function)ornull(认为是对空对象的引用)"function":function(在ES中被认为是对象,不代表数据类型,有自己的特殊属性)"symbol"1.Undefined类型一般不用于显式赋值,字面量undefined主要用于比较。建议在声明变量时对其进行初始化。如果typeof变为undefined,则可以确定该变量未声明。undefined是false值,检测的时候一定要明确:是否检测undefined字面值是否为false值。变量未声明时唯一可以执行的操作:typeof2.Null类型表示空对象指针。只有一个值:null。初始化一个变量用来保存以后对象的值,推荐使用null。可以维护null是空对象指针的语义。undefined派生自null。所以ECMA-262将它们定义为表面上相等(==等于运算符)。null是false值,检测的时候一定要明确:是检测null字面量还是false值。3.Boolean类型有两个字面值true和false。所有其他ECMAScript类型的值都具有对应布尔值的等价物。您可以使用Boolean()转换函数将其他类型的值转换为布尔值。False值:string:空字符串number:0,NaNobject:nullundefinedboolean:false4.Number类型使用IEEE754格式来表示整数和浮点数(双精度数)。不同的数字类型(不同的基数)有不同的数字字面量格式。前缀:八进制0o,十六进制:0x在所有数学运算中都被视为十进制数浮点值必须包含小数点,并且小数点后必须至少有一位数字。因为存储浮点值使用的内存是存储整数值的两倍,所以ECMAScript总是想方设法将值转换为整数。1)小数点后无数字;2)非常大或非常小的值后跟0可以用科学记数法表示(格式:一个值+E/e+10要乘多少次)。默认情况下,ECMAScript将小数点后至少包含6个零的浮点值转换为科学记数法。浮点值的精度可达小数点后17位,但在算术计算中远不如整数精确。(比如检查两个数之和是否为0.3)由于内存限制,值的范围不支持世界上所有的值。Number.MIN_VALUE-大多数浏览器中的5e-324Number.MAX_VALUE-1.7976931348623157e+308在大多数浏览器中超出了可表示范围并自动转换为特殊的无穷大值:Infinity(Numer.POSITIVE_INFINITY)和-Infinity(数字.NEGATIVE_INFINITY)。不能进一步用于任何计算。isFinite()函数可以用来检测判断是否超出范围。NaN用于指示本应返回值的操作失败(而不是抛出错误)。任何涉及NaN的操作总是返回NaNNaN不等于包括NaN在内的任何值。isNaN()函数将尝试将参数转换为值。3个函数:Number()、parseInt()和parseFloat()。Number()是一个转换函数,可用于任何数据类型;后两者主要用于将字符串转换为数字。字符串转换规则:包含数字字符包含有效的浮点值格式包含有效的十六进制格式空字符串-0包含上述以外的字符-NaN对象转换规则:如果转换结果为NaN,则调用valueOf()方法,继续调用toString()方法。一元加运算符遵循与Number()函数相同的转换规则。当转换一个字符串需要得到一个整数时,可以先使用parseInt()函数:从第一个非空格字符开始转换。空字符串->NaN。可选的第二个参数用于指定基数(基数)。parseFloat()函数:1)始终忽略前导零;2)只解析十进制值5.String类型表示零个或多个16位Unicode字符的序列。一些字符字面量:字符\xnn,用来表示非打印字符或其他用途,十六进制代码nn表示的字符,如\x41等于“A”。\unnnn,十六进制编码nnnn表示的Unicode字符,如\u03a3等同于希腊字符“Σ”。可以解释为单个字符。.length返回字符串中16位字符的数量。(如果包含双字节字符,返回的值可能不是准确的字符数)特点不能销毁:要修改变量中的字符串值,必须先销毁原来的字符串,再销毁包含新字符串的另一个字符串value必须被销毁字符串被保存到这个变量中。使用toString()方法转换为字符串:数值、布尔值、对象和字符串值。null和undefined什么都没有。调用该值时,它可以接收一个指定基数的参数。String()转换函数可应用于null和undefined(不确定时)。如果该值具有toString()方法,则调用该方法并返回。字符串(空);//“空”字符串(未定义);//"undefined"String(Object.create(null));//TypeError:CannotconvertobjecttoprimitivevalueUsetheplusoperatortoaddavaluetoavalue空字符串也和String()函数有同样的效果.模板文字,使用反引号将保留反引号内的空格和换行符。一种特殊的JavaScript语法表达式。特性:支持字符串插值:任何插值变量都从它们最近的范围获取它们的值(使用toString()强制)。定义后立即计算并转换为字符串实例。支持定义标签函数:将接收由插值标记分隔的字符串数组和每个插值表达式的求值结果。示例:让a=6,b=9;functionsimpleTag(strings,aValExp,bValExp,sumExp){console.log(strings);}让untaggedResult=`${a}+${b}=${a+b}`;console.log(untaggedResult);//"6+9=15"lettaggedResult=simpleTag`${a}+${b}=${a+b}`;//["","+","=","",raw:Array(4)]因为表达式参数的数量是可变的,所以通常使用rest运算符将它们收集到一个数组中:functionsimpleTag(strings,...expressions){console.log(strings);}//连接contentsofstringsandexpressions得到与untaggedResult相同的结果RawstringString.raw//tagfunction//可以直接得到原始模板字面量内容(例如换行符或Unicode字符),而不是转换后的字符。//但不是对于实际的换行符。label函数的第一个参数,也就是字符串数组,有一个raw属性,可以获取每个字符串的原始内容。6.符号类型原始值。独一无二且不可改变。目的:确保对象属性使用唯一标识符而没有属性冲突的危险。用于创建唯一标记以用作非字符串形式的对象属性。没有文字语法,不能用作构造函数(避免创建符号包装对象)String(Symbol());//"符号()"对象(符号());//符号{Symbol()}Object(Symbol()).toString();//"Symbol()"基本用法Symbol()或Symbol('xx')。参数与符号定义或标识完全无关,只是使用全局符号注册表对符号的描述目的:不同部分需要共享和重用符号实例。如何:使用字符串作为键在全局符号注册表中创建和重用符号。Symbol.for('xx');对每个字符串键执行幂等操作。必须使用字符串键创建(转换为字符串)。Symbol.keyFor(s);返回对应于全局符号的字符串键。非全局符号返回undefined;非符号抛出TypeError。主要目的是使用符号作为属性键Object.getOwnPropertySymbols();Object.getOwnProperyDescriptors();Reflect.ownKeys();如果不显式保存对符号键的引用,则必须遍历对象的所有符号键才能找到对应的属性键。常用的内置符号:全局函数Symbol的常用字符串属性用于暴露语言的内部行为,开发者可以直接访问、重写或模拟这些行为。.最重要的用途之一:重新定义它们,从而改变本机结构的行为。名称:规范中的名称,以@@为前缀。比如@@iterator,它是Symbol.iteratorSymbol.asyncIteratorES9的一个方法,返回对象默认的AsyncIterator。表示实现异步迭代器API的function函数生成的对象(迭代器?)应该通过它的next()方法一个接一个地返回Promise实例。for-await-of使用Symbol.hasInstance方法来确定构造函数对象是否识别对象是其实例。定义在Function的原型上,默认可以在所有的函数和类上调用。可以通过继承类上的静态方法重新定义此函数。由instanceof运算符使用。ClassA[Symbol.hasInstance](obj);相当于objinstanceofClassASymbol.isConcatSpreadable,一个boolean值,如果为true,对象应该用Array.prototype.concat()展平它的数组元素。Arrayobject:默认情况下,它会展平到现有数组,false或false值将作为一个元素追加到数组末尾Array-likeobject:默认情况下,它会作为元素追加到数组末尾一个元素,true或true值会将此类似数组的对象附加到数组的末尾Flattentoanarrayinstanceandothernon-array-likeobjects:默认情况下,它将作为元素附加到数组的末尾,如果为true或true将被忽略。Symbol.iterator返回对象默认迭代器的方法。表示在实现迭代器API的for-of函数中用于字符串匹配的符号。Symbol.match(接收参数:字符串实例):正则表达式方法,使用正则表达式匹配字符串。RegExp的原型默认有这个函数的定义。由String.prototype.match()方法使用:传入的非常规值将被转换为RegExp对象。Symbol.replace(接收两个参数:字符串实例和替换字符串):一种正则表达式方法,用于替换字符串中匹配的子字符串。RegExp的原型默认有这个函数的定义。由String.prototype.replace()方法使用:传入的非常规值将被转换为RegExp对象。Symbol.search(接受一个参数:字符串实例):一种正则表达式方法,返回字符串中与正则表达式匹配的索引。RegExp的原型默认有这个函数的定义。String.prototype.search()方法使用:传入的非常规值会被转换成RegExp对象,默认等于.match结果的index属性值(?)Symbol.split(接收一个参数:字符串实例):正则表达式方法,在匹配正则表达式的索引位置拆分字符串。RegExp的原型默认有这个函数的定义。String.prototype.split()方法使用:传入的非常规值将被转换为RegExp对象Symbol.species的函数值,作为创建派生对象的构造函数。常用于内置类型的派生类型,以覆盖新创建实例的原型定义。(实例方法的返回值暴露了实例化派生对象的方法)classBazextendsArray{staticget[Symbol.species](){returnArray;}}Symbol.toPrimitive一种将对象转换为其对应原始值的方法。由ToPrimitive抽象操作使用。根据提供给此函数的参数(字符串、数字或默认值),可以控制返回的原始值。Symbol.toStringTag用于创建对象的默认字符串描述的字符串。由内置方法Object.prototype.toString()使用。像[objectXXX]Symbol.unscopables这样的对象,该对象的所有和继承的属性将从关联对象的with环境绑定中排除。设置这个符号,让它把对应属性的键值映射为true,可以防止该属性出现在with环境中。让o={foo:'bar'};with(o){console.log(foo);//bar}o[Symbol.unscopables]={foo:true};with(o){console.log(foo);//ReferenceError:fooisnotdefined}7.对象类型是数据和函数的集合。在ECMAScript中,对象是派生其他对象的基类。运算符ECMA-262描述了一组可用于操作数据值的运算符。当应用于对象时,运算符通常调用valueOf()和/或toString()方法来获取可计算值。一元运算符(unaryoperator):只运算一个值自增/自减运算符(前缀,先计算再计算表达式;后缀,先计算表达式再计算):其他类型的值转换为Number类型后在值的前面加一个一元没有效果,它会执行与非数字值之前的Number()转换函数相同的效果。如果数值前面减去一元,就会变成负值。在非数字值之前,它会执行与Number()转换功能相同的操作。效果,再取负值位运算符:值的底层运算,即运算内存中代表数据的位(bit),不直接应用64位表示,而是先取值转换为32位Integer,然后进行位操作,再将结果转换为64位。有符号整数(默认):第32位表示值的符号(signbit,符号位),它决定了其余值的格式。正值以真正的二进制格式存储,负值以称为二进制补码的二进制编码存储(求绝对值,按位求反(一的补码),加一)。无法访问符号位。NaN和Infinity在位运算中都被视为0。当应用于非数值时,首先会通过Number()函数将其转换为数值。BitwiseNOT:用波浪符(~)表示,作用是返回值的补码。效果与取反减1相同。~~n等于n对于整数~~n等于n的整数部分,对于非整数值,按位与:&。仅当两位都为1时才返回1。按位或:|。如果两个位中至少有一个为1,则返回1。按位异或:^。只有一位为1才返回1。得到的结果小于等于按位或按位与+按位异或=按位或(?)左移的结果:<<。右端用0填充,保留操作数值的符号。签名右移:>>。左端填充无符号右移符号位的值:>>>。左边的空格会加0,符号位也随之移动。布尔运算符:非布尔类型,首先将操作数转换为布尔值逻辑非:!逻辑与:&&短路运算符。如果第一个操作数确定结果(false),则永远不会评估第二个操作数。逻辑或:||也是一个短路运算符。如果第一个操作数是(true),则不会计算第二个操作数。可用于避免将null或未定义(首选,备用)乘法运算符分配给变量。在处理非数值时,它还包括一些自动类型转换乘法运算符:*infinite*0=>NaNinfinite*not0=>Infinity/-Infinityany*NaN=>NaN除法运算符:/anyoperandisNaN=>NaN0/0=>NaNinfinite/infinite=>NaNnot0/0=>Infinity/-Infinityinfinite/any=>Infinity/-Infinitymodulooperator:%takeremainderinfinite%anyvalue=>NaNfinite%infinite=>无限/-无限本身是有限的%0=>NaN指数运算符:**。等同于Math.pow()。您还可以使用**=additive运算符加法。两个操作数都是数值。至少一个操作数是字符串(另一个操作数被转换为字符串)。如果字符串连接和减法中存在非数值,则将其转换为数值。然后计算关系运算符,包括小于、大于、小于等于、大于等于所有值,进行值比较都是字符串,一个一个比较字符串中对应字符的编码,如果任何一个操作数是一个值,转换另一个如果进行数值比较时任何操作数是一个对象,根据结果调用valueOf()进行比较。如果没有valueOf,则调用toString()方法。如果任何操作数是布尔值,则在执行比较之前将其转换为数值。相等运算符equality和inequality都返回false,在比较之前执行类型转换。强制类型转换规则:任何操作数都是布尔值;然后将其转换为一个值字符串,一个值;然后尝试将字符串转换为值并且有一个对象,另一个没有;然后调用对象的valueOf()方法获取其原始值比较规则:null和undefined相等,两者都不能转换为其他类型的值再比较任何操作数为NaN,相等运算返回false,不相等操作返回true都是对象,指向同一个对象相等操作返回true,否则返回false。全等和非全等比较不会转换操作数。仅当它们在没有转换的情况下相等时,全等运算才为真。建议使用一致性和不相等性以帮助维护代码中的数据类型完整性。条件运算符:三元运算符(?:)赋值运算符:将右边的值赋给左边的变量。复合赋值(简写语法,不会提高性能):*=|/=|%=|+=|-=|<<=|>>=|>>>=|一个值的常见场景:同时声明多个变量语句以分号结尾。可以省略(由解释器决定语句在哪里结束)。添加分号的好处:避免不完整的输入通过去除空行方便压缩代码在某些情况下有助于提高性能(减少解释器的分析工作)使用代码块(左右花括号{})的好处:使内容更清晰减少修改代码时出错的可能性控制流语句:if语句。自动调用Boolean()函数将表达式转换为布尔do-while语句。测试后循环语句,其中循环内的代码至少执行一次while语句。一是先测试循环语句,循环体中的代码可以不执行for语句。它还首先测试语句,在进入循环之前添加初始化代码,在每次循环执行后添加要执行的表达式。不需要任何初始化、条件表达式和循环后表达式。可以创建无限循环。如果只包含条件表达式,实际上就变成了一个while循环for-in语句。严格迭代语句,用于枚举对象中的非符号键属性为了保证局部变量不被修改,建议使用constobjectpropertiesareunordered,这样for-in语句不能保证返回对象属性的顺序for-of语句。用于遍历可迭代元素的严格迭代语句。可迭代对象的默认迭代器的next()方法产生值以按顺序迭代元素;如果您尝试迭代的变量不支持迭代,则会抛出TypeError标签语句。用于标记语句典型应用场景:嵌套循环label:statementstart:for(leti=0;i<5;i++){}breakandcontinuestatementsbreak:退出循环continue:退出当前迭代,进行下一次迭代可以与标签语句一起使用以返回到代码中的特定位置,通常与嵌套循环中的语句一起使用。将代码范围设置为特定对象。主要场景:如何在重复操作对象的with代码块中查找变量:1)查找局部变量;2)如果没有找到,则搜索with绑定的对象,看是否有同名属性;3)如果没有找到,继续沿着作用域链查找。严格模式不允许switch语句。与if语句相关的控制流语句。为了避免不必要的条件判断,最好在每个条件后面加上break语句;如果确实需要连续匹配几个条件,建议写注释。ECMAScript中的特点:可以用于所有数据类型(很多语言只用于数值),字符串甚至对象都可以使用。条件的值(case后面的值)不需要是常量,也可以是变量或者表达式letnum=25;switch(true){casenum<0:break;casenum>=0&&num<=10:break;casenum>10&&num<=20:break;default:;}//条件的表达式分别求值,直到一个表达式返回真,否则会跳转到默认语句//比较每个条件当值为时,可以使用恒等运算符函数来包装语句。无需指定是否返回值。除了函数返回值的return语句外,没有其他特殊声明。return语句也可以没有返回值,这种情况下函数会立即停止执行并返回undefined;它最常用于提前终止函数执行。最佳实践:要么返回值,要么不返回值。而不是仅在特定条件下返回值。