let和var区别
{
var a = 1;
let b = 2;
}
console.log(a);
console.log(b);//报错:ReferenceError: b is not defined。
如上可以发现:let声明的变量只会在它所在代码块中有效。
“=”“==”和“===”区别
如上分别为赋值运算符,相等运算符和严格相等运算符
console.log(1 == "1") //返回true
console.log(1 === "1") //返回false
上面代码中,===
比较他们的值,并且比较是否是同一种类型。
注意:NaN === NaN 结果是false,NaN与任何值都不相等(包括自身)
建议在书写条件表达式时,将常量放在前面,一旦少些了等号,则会编译报错提醒
if(x = 2){}
if(2 = x){} //会报错。修改为if(2 == x){} 即可
switch
var x = 1;
switch (x) {
case true:
console.log('x发生类型转换');
default:
console.log('x没有发生类型转换');
}
// x没有发生类型转换
通过如上代码可以看出,switch后的表达式和case后的表达式比较时,采用的“严格相等运算符”进行比较,x并未发生类型转换。
标签
JavaScript语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
标签可以是任意的标识符,但是不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
上面代码为一个双重循环区块,break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2
上面代码中,continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。
构造函数
在Java的概念中,存在“类”这个概念。
类 是对象的模板,对象 是“类”的实例。
而在JavaScript中,对象是基于构造函数(constructor)和原型链(prototype)的。
JavaScript中使用构造函数作为对象的模板。
所谓“构造函数”,就是专门用来生成对象的函数。它提供模板,描述对象的基本结构
其写法就是一个普通的函数,但有自己的特征和用法。
var Vehicle = function () { //函数名首字母大写
this.price = 1000;
};
特点:
- 函数体内部使用了this关键字,代表了所要生成的对象实例。
- 生成对象的时候,必需用new命令,调用Vehicle函数。
使用new命令执行构造函数,才能生成实例对象。否则返回的实例对象是undefined。且导致内部的this代表全局变量。
为了解决不使用new带来的问题,可以用如下两种方法解决
1.使用'use strict';
不调用new调用则会报错。
function Team(num) {
'use strict';
this._num = num;
}
console.log(Team(10));//TypeError: Cannot set property '_num' of undefined
2.内部判断,默认返回一个实例对象
function Team(num) {
if(!(this instanceof Team)){
return new Team(num);
}
this._num = num;
}
console.log(Team(10));
prototype属性的作用
JavaScript的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。只有null除外,它没有自己的原型对象。
原型对象上的所有属性和方法,都能被派生对象共享。这就是JavaScript继承机制的基本设计。
通过构造函数生成实例对象时,会自动为实例对象分配原型对象。每一个构造函数都有一个prototype属性,这个属性就是实例对象的原型对象。
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。而通过构造方法生成的对象,属性都是独立的 参考链接
原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的含义,而实例对象可以视作从原型对象衍生出来的子对象。
call 、apply、bind方法的区别
函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
var n = 123;
var obj = { n: 456 };
function a() {
console.log(this.n);
}
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456
call方法指定函数a内部的this到obj中,在obj中执行a函数。