1.在使用<script>嵌入JS代码时,任何地方都不要出现 "</script>"字符串。
2.使用defer属性可以让脚本在文档完全呈现之后再执行,且按顺序执行。
使用async属性可以表示当前脚本不必等待其他脚本,也不必阻塞文档呈现,不保证安顺序执行
3.函数中省略var定义变量,那这个变量会被定义为全局变量。
let声明的变量不会挂载到window上。
4.对未初始化的变量执行typeof操符回返回undefined值,而对未声明的变量执行typeof操作符同样会返回undefined值。
5.八进制字面值:第一位必须是零(0),然后八进制数字序列,如果字面值的数值超出了范围,那么前导零将被忽略。
let a=070 //56
let b=079 //79
十六进制字面值的前两位必须是0xI(区分大小写),后跟任何十六进制数字(0~9及A~F),字母大小写均可。
6.对于对象调用Number()函数,先调用对象的valueOf()方法,然后依照前面的规则转换返回的值,如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
7.parseInt()函数在转换字符串时,更多的是看其时候符合数值模式,他会忽略字符串前面的空格,直至找到第一个非空格字符串,如果第一个字符不是数字或者负号,就会返回NaN。
8.null和undefined没有toString方法,对于null和undefined使用String()方法。
其实String()的本质是调用了toString()方法,只是处理了null和undefined两种特殊情况。
9.switch语句在比较值时使用的是全等操作符,因此不会发生类型转换。
10.函数的参数可以想象为一个局部参数。
function setName(obj){
obj.name="niko"
obj=new Object()
obj.name='s1mple'
}
var person=new Object()
setName(person)
console.log(person) //niko
11.模版字面量也支持定义标签函数,而通过标签函数可以自定义插值欣慰,标签函数会接收被插值极好分割后的模版和每个表达式求值的结果,标签函数本身也是个常规函数,通过前缀到模版字面量来应用自定义行为。
let a =6
let b=9
function simpleTag(string,...expresions){
console.log(string)
for(const key of expresions){
console.log(key)
}
return 'sss'
}
let taggedResult=simpleTag`${a}+${b}=${a+b}`
console.log(taggedResult)
//["", "+", "=", ""]
// 6
// 9
// 15
//"sss"
12.使用模版字面量也可以直接获取原始的模版字面量内容(如换行符:\n)而不是呗转换后的字符表示,为此,可以使用默认的String.raw标签函数。
13.Symbol()函数不能与new关键字一起作为构造函数使用,这样做是为了避免创建符号包装对象。
14.number方法:toPrecision()会风局情况返回最合理的输出结果,可能是固定长度,有可能是科学计数法形式,这个方法接受一个参数,表示结果中数字的总位数(不包含指数)
let num= 99;
console.log(num.toPrecision(1));//'1e+2' -->对99四舍五入了
console.log(num.toPrecision(2));//‘99’
console.log(num.toPrecision(3));//‘99.0’
15.slice()、substr()、substring(),对于某个参数是负值时的不同处理:
slice:将所有负值参数都当成字符串长度加上负参数值。
substr:降低一个负参数值当成字符串长度加上该值,将第二个负参数值转换成0。
substring:将所有负参数值都转换为0。
let stringValue = "hello world";
console.log(stringValue.slice(-3)); //8 rld
console.log(stringValue.substring(-3)); //0 hello world
console.log(stringValue.substr(-3)); //8 rld
console.log(stringValue.slice(3, -4)); //3-8 lo w
console.log(stringValue.substring(3, -4)); //3-0 hel
console.log(stringValue.substr(3, -4)); //3,0 ''
16.通过eval()定义的任何变量和函数都不会被提升,只是因为在解析代码的时候,他们是被包含在一个字符串中的,他们只是在eval()执行的时候才会被创建。
eval("let msg='ssss';")
console.log(msg) // "Uncaught ReferenceError: msg is not defined"
17.使用instance佛的问题是假定只有一个全局执行上下文,如果网页中有多个框架,则可能涉及两个不同的全局上下文,因此就有两个不同版本的Array构造函数,如果要把数组从一个框架传个另一个框架,则这个数组的构造函数将有别于第二个框架内本地创建的数组。
18.数组splice()的返回值是被删除的项。
19.WeakMap的键只能是Object或者继承自Object的类型,WeakSet的值只能是Object或者继承自Object的类型。
20.Object属性的类型:
数据属性:数据属性包含一个保存数据值的位置,值会从这个位置读取,也会写入这个位置,数据属性有四个特性描述它们的行为:Configurable,Enumerable,Writable,Value.
访问器属性:访问器属性不包含数据值,相反,他们包含一个获取函数和一个设置函数,不过这个两个函数不是必须的。访问器属性有四个特性描述它们的行为:Configurable , Enumerable ,Get,Set.
21.使用new操作符:
在内存中创建一个新对象
这个对象内部的[[Prototyoe]]特性被赋值为构造函数的prototype属性
构造函数内部的this被赋值为这个新对象(即this指向新对象)
执行构造函数内部的代码(给新对象添加属性)
如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象
22.重写整个原型会切断最初原型与构造函数的关系,丹实例引用的仍然是最初的原型。实例只有指向原型的指针,没有指向构造函数的指针。
function Person(){}
Person.prototypr={
constructor:Person,
name:'Niko',
age:29,
job:'software Engineer',
sayHi(){
console.log('hi')
}
};
friend.sayHi()//错误
23.函数受函数作用域的限制,而类受块作用域限制
{
function test(){}
class ClassTest(){}
}
console.log(test)// test(){}
console.log(ClassTest)//ReferenceError
24.使用super时的注意点:
super只能在派生类构造函数和静态方法中使用。
不能单独引用super关键字,要们用它调用构造函数,要么用它引用静态方法。
调用super()会调用父类构造函数,并将返回的实例赋值给this
super的行为如同调用构造函数,如果需要给父类构造函数传参,则需要手动传入
如果没有定义类构造函数,在实例化派生类时会调用super(),而且会传入所有传入给派生类的参数
在类构造函数中,不能在调用super()之前引用this
如果在派生类中显式定义了构造函数,则要么必须在其中调用super,要么必须在其中返回一个对象
25.函数是ECMA中最有意思的部分之一,这主要是因为函数实际上是对象,每个函数都是Function类型的实例,而Function也有属性和方法,跟其他引用类型一样,因为函数是对象,所以函数名就是指向函数对象的指针,而且不一定与函数本身紧密绑定。
26.ES6的所有函数对象都会暴露一个只读的name属性,其中包含关于函数的信息,多数情况下,这个属性中保存的就是一个函数表示符,或者说是一个字符串化的变量名,即使函数没有名称,也会如实显示成空字符串,如果它是使用Function构造函数创造的,则会被表示成‘anonymous'
27.函数如果只传一个参数,然后把arguments[1]设置为某个值,那么这个值并不会反映到第二个命名参数,这是因为arguments对象的长度根据传入的参数个数,而非定义函数时给出的命名函数的个数确定的。
function test(num1,num2){
console.log(arguments.length)//1
arguments[1]=10
console.log(num1,num2,arguments[1])//10,undefined,10
}
test(10)
28.箭头函数没有arguments对象。
29.在使用默认参数时,arguments对象的值不反应参数的默认值,只反映传给函数的参数。
30.js引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义,这个过程叫做函数声明提升;而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
31.arguments.callee就是一个只想正好在执行的函数的指针
32.闭包外层函数在执行完后,其执行上下文的作用域链会销毁,但它的活动对象仍然会保留在内存中,直到被返回的函数被销毁后才会销毁。
注:活动对象:在函数局部上下文中,包含其中变量的对象,叫做活动对象。
全局对象:包含全局上下文中的变量的对象叫做全局对象。
33.onRejected处理程序返回的值耶会被Promise.resolve()包装,乍一看可能有点违反直觉,但是想一想,onRejected处理程序的任务不就是捕捉异步错误吗,硬刺拒绝处理程序在捕获错误后不抛出异常是符合期约的行为,应该返回一个解决的契约。
34. 所有超时执行的代码(函数)都会在全局作用于中的一个匿名函数中运行,因此函数中的this值在非严格模式下始终指向window,而在严格模式下是undefined。
持续更新中......