为什么JavaScript不是编译型的?
使用C、C++等传统编程语言时,执行代码前必须进行编译。编译是将代码转换为适合计算机的表示方法,通常可改善运行阶段性能。脚本语言通常是解释型的,浏览器执行它遇到的每行JavaScript代码。脚本语言不那么看重运行阶段性能,而更强调灵活性,更适合用于原型开发和交互式编码等任务。浏览器厂商对现代JavaScript采取的做法是进行即时编译。JavaScript既可以获得脚本语言的便利性,又可以拥有编译语言的性能。
向NaN传递一个不能转换为数字的字符串是,它会返回true吗?
如果变量存储的是NaN或其他任何不是数字的值,将其传递给isNaN时,它都将返回TRUE
为什么NaN与它自己不相等?
IEEE浮点数规范。NaN指的是无法表示的数字,但并非所有无法表示的数字都相等。
Infinity与NaN
在JavaScript中,infinity指的是超过浮点数上限1.7976931348623157E+10308的值。-Infinity指的是超过浮点数下限-1.7976931348623157E+10308的值。
类型转换。
只要有一个操作数是字符串,就会把+视为字符串拼接。 但是+的结合性是从左到右的。
布尔值+字符串的结果为字符串
检查两个对象是否相等时,比较的是指向对象的引用。仅当两个引用指向的是同一个对象时,他们才相等。
假值
JavaScript中只有五个假值:undefined,null,0,空字符串,NaN。其他的值都是真值。
函数声明为什么不是表达式?
函数声明是一条语句。可以认为它包含一条隐藏的赋值语句,这条语句将函数引用赋值给一个变量。函数表达式不自动将函数引用赋给任何变量。
函数声明和函数表达式
无论使用函数声明还是函数表达式,最终都将得到一个函数。
- 使用函数声明时,函数将在执行代码前创建;而使用函数表达式时,函数将在运行阶段创建。
- 使用函数声明时,将创建一个与函数同名的变量,并让它指向函数,而使用函数表达式时,通常不给函数指定名称。
函数是一等公民
一等值可以:
- 将其赋值给变量或者存储在数组和对象等数据结构中
- 将其传递给函数
- 从函数中返回他们
向函数传递参数时,传递的是什么?
传递的是指向函数的引用(可视为指针)。它指向函数本身的内部表示。
词法作用域
词法意味着只需查看代码的结构就可确定变量的作用域。
词法作用域是指JavaScript的作用域规则完全基于代码的结构。只需要查看代码的结构就可以确定变量是在什么地方定义的。
闭包
函数通常包含局部变量,还可能包含不是在本地定义的变量,这些变量称为自由变量。包含自由变量的函数与为所有这些自由变量提供了变量绑定的环境一起,被称为闭包。环境引用的是实时变量。
var secret='007'
function getSecret(){
var secret='008'
function getValue(){
return secret;
}
return getValue()
}
console.log(getSecret())
//008
var secret='007'
function getSecret(){
var secret='008'
function getValue(){
return secret
}
return getValue
}
console.log(getSecret()())
//008
var secret='007'
function getSecret(){
// var secret='008'
function getValue(){
return secret;
}
return getValue()
}
console.log(getSecret())
//007
对象字面量与构造函数
需要创建少量对象时,适合使用对象字面量。 需要创建大量类似对象的时候,适合使用构造函数。
原型
js中没有传统的面向对象的模型(从类创建对象的模型)。js中从其他对象那里继承行为,称为原型式继承或者基于原型的继承。 给原型添加新的方法或属性后,继承该原型的对象的所有实例对象都将立即看到它。
function Dog(name,age){
this.name=name
this.age=age
}
Dog.prototype.bark=function(){
console.log('woof')
}
let puppy=new Dog('coco',1)
puppy.bark()
Dog.prototype.eat=function(){
console.log('eating')
}
puppy.eat()
// woof
//eating
修改原型的任何属性,都将影响继承该原型的所有对象——只要他们没有重写这个属性。