let和const
let块级作用域:{就是代码块}向上寻找距离该变量最近的开始的函数的{作用范围就是该{}之内
{
let a=10;
}
console.log(a);会报错 let作用域是代码块以内的区域
let不能重复声明
会报错'm' has already been declared
let m=100;
let m=1;
没有变量提升的概念
Cannot access 'm' before initialization
console.log(m);
let m=10;
暂时性死区:在一个代码块内,如果有某个变量,会绑定该区域,不再受外界的影响,let没有变量提升的概念
let声明变量之前,不能使用
let m=100;
{
console.log(m); 暂时性死区
let m=10;
}
// 重复声明
// let a=10;
// var a=10;
//重复声明
// let a=10;
// {
// var a=10;
// }
// 不会报错
// var a=10;
// {
// let a=10;
// }
// let a=10;
// {
// var a=10;
// }
let a=10;
(function add(){
var a=10;
}
)();
const
声明的是常量,值是不可以改变的(不能重新赋值),其余语法和let一样
const a=5000;
// a=100;
// stu是对象,在内存中以地址的形式存储,
const stu={
name:'zs'
}
// 修改了数据。所以地址没有变化。不会报错
stu.name='ls';
// 重新赋值会报错。
stu={
name:'ls'
}
字符串扩展
var pro={
title:'华为手机',
price:4999
}
product.innerHTML+="<tr><td>"+pro.title+"</td><td>"+pro.price+"</td></tr>";
// 模板字符串 在变量和常量拼接的时候使用 整个字符串使用`${变量}`
product.innerHTML+=`<tr>
<td>${pro.title}</td>
<td>${pro.price}</td>
</tr>`;
// 标签模板 ``可以跟在一个函数后面,该函数将被调用来处理这个模板字符串。这被称为模板标签功能
// alert(123);
// alert`123`;
//
function fn(x,y){
// console.log(x,y)
console.log(arguments);
};
// fn(1,23);
// 解析函数参数的时候,会把参数解析成一个数组形式
fn`1,23,23,23,45`;
// 模板字符串作为函数参数参数存在。会执行函数。自动解析参数 把所有常量拼接成一个数组。变量依次拼接到数组后面
var m=10;
var n=100;
fn`hello${m}zsh${n}m${m+n}n`;
// 等价于
// fn(['hello','zsh','m','n'],m,n,m+n);
解构
解构:es6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这称为解构
es5中,如果对多个变量赋值
let a=10;
let b=100;
let c='h';
// 数组的解构,按照数组顺序依次赋值。如果变量多余,相当于声明不赋值。如果数据多余,对变量没有影响
var [a,b,c,d]=[10,100,'h',12,3,4,4,5];
console.log(a,b,c,d);
// 快速交换值
let m=12;
let n='my';
[n,m]=[m,n];
console.log(m,n);
对象的解构赋值 使用的是{}
对象的解构与数组的解构有一个重要的不同,数组的元素是按次序排列的
数组解构中,变量的值由所处的位置决定。对象的属性没有次序,变量必须与属性同名才可以,才可以取到正确的值。
var stu={name:'zs',age:12};
// hobby相当于声明了没有赋值。
let {name,age,hobby}=stu;
console.log(name,age,hobby);
// 字符串的解构。按照字符串的顺序依次赋值和数组解构类似
let [x,y,z]='hello';
console.log(x,y,z);
// 类似数组的对象都有一个length属性,可以对该属性进行解构赋值。
let {length:len}='zsh';
console.log(len);
// 函数的解构赋值,类似于数组的解构解构
function add([a,b]){
console.log(a,b);
console.log(a+b)
}
add([3,4]);
// 相当于把字符串3赋值给了a 字符串4赋值给了b
add('34');
数组扩展
var arr=new Array(10);
// 长度为10的数组。
console.log(arr);
// Array.of()对new Array()的扩展 。不论输入什么,都代表的是数组元素。
arr=Array.of(10);
console.log(arr);
// Array.from()把类数组转化为数组
var btns=document.getElementsByTagName('button');
console.log(btns);
console.log(btns instanceof Array);
btns=Array.from(btns);
// foreach不能用来遍历类数组,能遍历数组
btns.forEach(function(item,index,arr){
console.log(arr);
})
// 类数组 一定要严格按照格式来写 属性名是0 1 2 并且一定要有length。如果转化为了数组,最终的长度由length的值
var arr1={
0:'z',
1:'s',
2:'h',
length:5
}
arr1=Array.from(arr1);
arr1.forEach(function(item,index,arr){
console.log(item);
})
var score=[98,60,48,56];
// 数组.find(function(n代表数组元素){条件})得到的结果是第一个符合条件的数组元素的值。从左到右寻找 如果找不到结果是undefined。
// var m=score.find(function(n){return n<0});
// console.log(m);
// 数组.findIndex(function(n代表数组元素){条件})得到的结果是第一个符合条件的数组元素的下标。从左到右寻找 如果找不到结果是-1。
var m=score.findIndex(function(n){return n>60});
console.log(m);
construto
construtor方法是类的默认方法,一个类必须有constructor方法。
如果没有显示定义,一个空的constructor方法会被默认添加
通过new命令生成实例对象的时候,自动调用该方法
constructor默认返回的是实例对象。完全可以指定返回另外一个对象
es6中的继承
es6中通过extends关键字实现继承。比在es5中通过原型链实现继承,要清晰和方便。更偏向传统编程语言
class Cat extends Animal{
constructor(name,color,type){
// super继承来自父级的属性(相当于把父级的属性一一复制过来)
// 如果constructor没有该属性传递不过来,直接书写属性会报错 super(name,color,price)
super(name,color);
this.type=type;
}
}
class Dog extends Animal{
constructor(name,color,price,type){
super(name,color,price);
this.type=type;
}
}
// 把实参的值,赋值给了constructor
var cat1=new Cat('花花','白色','波斯猫');
console.log(cat1);
// 属性是自有的,不继承。
console.log(cat1.hasOwnProperty('name'));
cat1.eat();
继承相关问题
原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或者方法,
就会去关联的prorotype那里寻找,如果prototype没有。就会去prototype关联的prototype那里寻找。如果还没有,会一直向上寻找
直到prototype....prototype..为null。从而形成了原型链(根本上来说就是继承)
a.isPrototypeOf(b) 判断a是否存在b的原型链中
在子类的constructor中必须要有super关键字,如果不写,会报错
子类的this关键字根据super方法创建
子类实例对象的构建,是基于父类实例进行加工。只有super方法才可以返回父类实例
super();
class Cat extends Animal{
constructor(name,color,type){
// super继承来自父级的属性(相当于把父级的属性一一复制过来)
// 如果constructor没有该属性传递不过来,直接书写属性会报错 super(name,color,price)
super(name,color);
this.type=type;
}
}
var c1=new Cat('花花','白色','波斯猫');
class BSM extends Cat{
constructor(){
// 在子类的constructor中必须要有super关键字,如果不写,会报错
// 子类的this关键字根据super方法创建
// 子类实例对象的构建,是基于父类实例进行加工。只有super方法才可以返回父类实例
// super();
}
}
var b1=new BSM();
console.log(Animal.prototype.isPrototypeOf(c1));
console.log(Animal.prototype.isPrototypeOf(b1));
console.log(Cat.prototype.isPrototypeOf(b1));
get和set
class Circle{
constructor(){
this.r=10;
}
// get方法 获取的值的时候会自动调用 一定要加返回值
get acr(){
return Math.PI*this.r*this.r;
}
// set方法 设置值的时候会自动调用 实参是通过等于号赋值。
set acr(value){
this.r=value
}
}
var c=new Circle();
// console.log(c.acr);
// 调用的是set方法
c.acr=1;
// 调用的是set方法
// console.log(c.acr);
静态方法和静态属性
// Math.random() Math.PI
class Cat{
// 类中的方法前面如果加了sataic关键字,该方法就是静态方法
// 静态方法只能通过类名直接调用。
static eat(){
console.log('这是静态方法,需要通过类直接调用')
}
}
// 静态属性指的是类本身有的属性,通过类名.属性名直接调用。不需要实例化对象调用
Cat.type='XXX';
var c=new Cat();
// c.eat(); 会报错 cat是静态方法
Cat.eat();
console.log(Cat.type);
// 静态方法和静态属性可以被子类继承
class Bsm extends Cat{
constructor(){
super()
}
}
Bsm.eat();
console.log(Bsm.type);
私有方法
class Cat{
eat(){
this._food()
}
// 在es6的提案,提到了如果方法名以_开始,默认只能在类中调用,不能被继承或者被实例对象使用,但是目前没有什么用
_food(){
console.log('这是水果');
}
}
var c=new Cat();
c._food();