02 变量扩展
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!--ECMAScript6.0简称ES6,它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言-->
<!--ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)。日常场合,这两个词是可以互换的。
-->
<!--2015年6月,ECMAScript6 正式通过,成为国际标准-->
<!--let声明的变量只在它所在的代码块有效-->
<!--
// 1.var 的情况
console.log(foo); // 输出undefined
var foo = 2;
//var命令会发生变量提升,即声明了但是此时没有值
-----------------------------------------------
// 2.let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
//let不会发生变量提升,表示在声明之前,变量不存在
-->
<!--const声明一个只读的常量。一旦声明,常量的值就不能改变-->
<!-- Babel把es6转化为es5的。 但是es6语法,大多数浏览器都兼容,所以没有必要专门引入-->
<!-- 变量提升:会把变量声明提升到作用域的最前面,赋值还是在原来的位置;
let变量声明:
1.不能重复声明 identifier 'a' has already been declared重复声明
2.块级作用域,一个{}就是一个代码块。作用域向上寻找距离该变量最近的开始{
3.没有变量提升。
4.暂时性死区
var声明的变量,函数作用域:作用域向上寻找距离该变量最近的开始的函数的{
全局变量var和局部变量let同时存在,局部变量优先;
//暂时性死区
//重复声明
var a=100
let a=10
let a=10;
{
var =10
} -->
<!----------作业------------>
<!--1.简述var 和let 区别是什么?
答:①var是全局变量,let是局部变量;
②var会发生变量提升,而let不会
2.下面程序执行结果是?
var a= 123;
if (true) {
a= 'abc'; // ReferenceError
let a;
}
执行结果:undefined ×
应该是:Uncaught ReferenceError: Cannot access 'a' before initialization
-->
<script>
// var a= 123;
// if (true) {
// a= 'abc'; // ReferenceError
// let a;
// }
// console.log(a);
// console.log(a);
// a=10;
// a is not defined
// function add() {
// console.log(a);
// var a='add'
// }
// undefined-->等价于 变量提升。全局变量和局部变量同时存在,局部变量优先
// function add() {
// var a;
// console.log(a);
// a='add';
// }
// add();
// undefined
// 在初始化之前无法访问 m Cannot access 'm' before initialization
// console.log(m);
// let m='这是m';
// 暂时性死区。出现原因:1.全局变量和局部变量同时存在,局部变量优先;2.没有变量提升
var m='hello';
{
console.log(m);
let m=10;
}
// Cannot access 'm' before initialization
</script>
</body>
</html>
03 let相关问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// <!--重复声明-->
var a=10;
let a=100;
// 重复声明
let a=10;
{
var a=10;
}
// 局部变量就会绑定该区域,不再受外界影响
var m='m';
{
let m='m';
}
</script>
</body>
</html>
04 let应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04let应用</title>
</head>
<body>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<script>
var btns=document.getElementsByTagName('button');
// for(var i=0;i<btns.length;i++){
// btns[i].οnclick=function () {
点击的时候才会执行。for循环已经执行完毕
// console.log(i);
// this.style.color='red';
// }
// }
for(let i=0;i<btns.length;i++){
btns[i].onclick=function () {
// 点击的时候,才会执行。for循环已经执行完毕
console.log(i);
this.style.color='red';
}
}
</script>
</body>
</html>
05 const
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--const用法和let一样,不能重复赋值,一经声明不能修改-->
<script>
//声明常量
const a=10;
// a=100; 如果有这行会报错,因为不能重复赋值
console.log(a);
// 修改整个变量会报错。单纯修改属性的值的话,不会报错
const stu={
name:'zs'
}
// 如果有这行会报错,因为不能直接修改整个变量
// stu={
// name:'ls'
// }
stu.name='ls'; //修改变量中属性的值,不会报错
console.log(stu);
</script>
</body>
</html>
06 字符串扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="txt">
<li>
<h1></h1>
<p></p>
</li>
</ul>
<script>
var oul=document.getElementsByTagName('ul')[0];
let pro={
title:'商品名字',
des:'描述性内容'
}
// txt.innerHTML=' <li ><h1>'+pro.title+'</h1><p>'+pro.des+'</p></li>'
//模板字符串:处理字符串拼接。 使用`反引号${变量}`
// txt.innerHTML=`<li >
// <h1>${pro.title}</h1>
// <p>
// ${pro.des}
// </p>
// </li>`
oul.innerHTML=`<li>
<h1>${pro.title}</h1>
<p>${pro.des}</p>
</li>`
// 标签模板。跟在函数后面,不再使用()而使用``
// alert(123);
// alert`123`;
function add(x,y,z) {
// arguments 用户输入的实参
// 函数形参的个数-->函数名.length
// console.log(add.length);
console.log(arguments);
}
add(1,2,3,4,5); //Arguments(5)
let a=10;
let b=20;
// 使用标签模板和()不一样,自动处理参数。
// 首先以变量${}作为分隔符。
// 把常量组合成一个数组作为一个实参,每一个常量都是一个单独的实参
add`1${a}hello${a+b}my`
// Arguments(3) [Array(3), 10, 30, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 0: Array(3)
// 0: "1"
// 1: "hello"
// 2: "my"
// length: 3
// raw: (3) ["1", "hello", "my"]
// __proto__: Array(0)
// 1: 10
// 2: 30
// callee: ƒ add(x,y,z)
// length: 3
// add`1,2,3,4,5${a}dsfd${b}`
// add`123${a}2${b}hello`
</script>
</body>
</html>
07 结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>解析重新构造(解构)</title>
</head>
<body>
<script>
//<!--解构:允许数组和对象,按照一定的方式对变量进行赋值-->
// <!--数组解构。数组元素依次赋值给变量-->
// let [a,b,c,d]=[1,2,3,4];
// console.log(a,b,c,d);
// 打印结果:1 2 3 4
// 相当于声明了z,但是没有赋值,undefined
// let [x,y,z]=[1,2,3,4,5];
// console.log(x,y,z);
// 打印结果:1 2 3
//如果有多余的值,不会报错
//let[x,y,z]=[1,2,3,4,5];
//console.log(x,y,z);
// 交换值
//let m=10;
//let n='hello';
//[n,m]=[m,n];
//console.log(m,n);
//打印结果:hello 10
//对象解构,和数组解构不一样,数组是有顺序的。对象只能按照属性来进行解构
// let {name,age}={
// name:'zs',
// age:12
// }
// console.log(name,age);
// 变量声明以后,一般不会报错
// let {n1,a1}={
// x:12,
// y:14
// };
// console.log(n1,a1);
// 打印结果:undefined undefined
// 字符串解构 和 数组解构类似
let[x1,y1,z1]='hello';
console.log(x1,y1,z1);
// 打印结果:h e l
// 字符串解构,特殊用法。len存储的是字符串的长度
let {length:len}='h';
console.log(len);
// 打印结果:1
</script>
</body>
</html>
08 数组扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组扩展</title>
</head>
<body>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<button>按钮</button>
<script>
// <!--创建长度为10的数组 new Array()如果只有一个数值,代表创建的是长度-->
var arr=new Array(10);
console.log(arr);
// 打印结果:Array(10)
// length: 10
// Array.of()相当于扩展了new Array()
// 创建长度为1的数组,值为10
var arr1=Array.of(10);
console.log(arr1);
// 打印结果:[10]
// 0: 10
// length: 1
var arr2=[1,2,3,4];
// 类数组
var btns=document.getElementsByTagName('button');
// 类数组对象,和数组类似
var arr3={
0:'math',
1:'chinese',
length:2
}
console.log(arr2);
console.log(btns);
console.log(arr3);
// Array.from()把类数组转化为数组
btns=Array.from(btns);
console.log(btns);
arr3=Array.from(arr3);
console.log(arr3);
// forEach专门用来遍历 数组,不能遍历 类数组
arr3.forEach(function (item, index, arr) {
// item数组元素
// index数组下标
// arr数组
console.log(item, index, arr);
})
let ar=[10,1,2,3,4];
// 数组.find(function(n){return 条件})找到第一个符合条件的元素,只找一个
let a1=ar.find(function (n) {
// n代表的是数组元素
return n>3;
})
// 数组.findIndex(function(n){return 条件})找到第一个符合条件的元素的下标,只找一个
let a1=ar.findIndex(function (n) {
// n代表的是数组元素
return n>3;
})
console.log(a1);
// 数组.filter(function(n){return 条件})找到所有符合条件的元素
let a2=ar.filter(function (t) {
return t>3&&t<6;
})
console.log(a2);
// splice(a,b,c) a开始的位置(从该位置开始执行),b删除个数,c插入元素
// ar.splice(1,0,'hello','welcome'); //在10和1之间插入元素,1之后的数字被挤到后面了
// console.log(ar);
// copyWithin(a,b,c) a替换开始的位置,b复制开始的位置(下标) c复制结束的位置(下标)
// 含开始不含结束 复制数组的一段元素,替换数组的一些元素
// 1.复制元素超出要替换的了,多余的直接省略;
// 2.复制的范围超出数组最大范围,直接省略多余范围;
// 3.开始的位置小于结束的位置
// 4.可以为负值,从右到左开始
// let ar=[10,1,2,3,4];
// 下标: 0 1 2 3 4
// -5 -4 -3 -2 -1
// ar.copyWithin(2,3,4);
// 打印结果:[10, 1, 3, 3, 4]
// ar.copyWithin(1,2,4);
// 打印结果:[10, 2, 3, 3, 4]
// ar.copyWithin(3,-4,-1);
// 打印结果:[10, 1, 2, 1, 2]
ar.copyWithin(0,-5,2);
// 打印结果:[10, 1, 2, 3, 4]
console.log(ar);
/*
splice : 删除了值和对应的空间
splice(index,len,[item])
注释:该方法会改变原始数组。
index:数组开始下标
len: 替换/删除的长度
item:替换的值,删除操作的话 item为空
var str= ['a','b','c','d'];
str.splice(1,1); 结果为:["a","c","d"] 直接删除了数组 改变了数组的值。
*/
</script>
</body>
</html>
09 函数扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>09</title>
</head>
<body>
<script>
function add(x,y) {
// 参数默认值,如果用户输入就是输入的值,否则就是5000
y=y||5000;
console.log(y);
}
// add(1,7000);
// es6默认参数的概念。y如果有值的话,实参为准;如果没有实参,默认为10
// function add(x,y=10) {
// console.log(y);
// };
// add(10);
// 打印结果:10
// undefied为空相当于没有传递参数
// add(10,undefined); //打印结果:10
// add(10,100); //打印结果:100
// 函数参数扩展,相当于解构
// let [x,y]=[1,2];
// function fn([x,y]) {
// console.log(x,y);
// }
// fn([1,3]);
// 打印结果:1 3
// 箭头函数 去除function()和{}中间加=>
// var fn=(x,y)=>{
// console.log(x,y);
// }
// fn(1,3);
// setTimeout(()=>{
// console.log(111)
// },1000)
// 如果函数体,只有一句代码{}也可以省略,但是如果这句代码包含return。去除return
// var fn=(x,y)=>console.log(x+y);
// var fn=(x,y)=>x+y
// console.log(fn(34,4));
// 打印结果:38
// 箭头函数,没有arguments概念,有了rest剩余参数的概念
// var add1=(...rest)=>{
// console.log(rest);
// }
// var add1=(...a)=>{
// console.log(a);
// }
var stu={
name:'zs'
}
var add1=(x,y,...a)=>{
console.log(this);
// Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …} 指向window
console.log(a);
// (2) [3, 4]
// ??
a.unshift(x,y);
console.log(a);
// (4) [1, 2, 3, 4]
}
add1(1,2,3,4);
// Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
add1.call(stu,1,2);
</script>
</body>
</html>
10 call apply bind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>10</title>
</head>
<body>
<script>
// this指向
// 事件中的this,指向事件源
// 普通函数中的this指向window
var stu={
name:'zs'
}
function add(x,y) {
console.log(x,y);
// 1 2
console.log(this);
// Window
}
// add(1,2);
// call apply bind的区别?
// 函数名.call(对象,实参) 直接调用函数 修改this的指向,指向的就是传递的对象
// add.call(stu,1,2);
// 1 2
// {name: "zs"} this此时指向的是stu对象
// 函数名.apply(对象,[实参])直接调用函数 修改this的指向,指向的就是传递的对象。
// add.apply(stu,[1,2])
// 1 2
// {name: "zs"} this此时指向的是stu对象
// 函数名.bind(对象,实参) 返回一个新的函数,不会直接调用 修改this的指向,指向的就是传递的对象。
fn=add.bind(stu,1,2);
fn();
// 1 2
// {name: "zs"} this此时指向的是stu对象
</script>
</body>
</html>
11 对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>day02对象</title>
</head>
<body>
<script>
// <!--对象-->
// var arr=[100,98,89];
// 对象:详细的描述事物
// 具体对象中的this代表的就是当前对象
// var score={
// math:100,
// chinese:90,
// sum:function () {
// console.log(this.math+this.chinese)
// }
// }
// score.sum();
// ----------03.工厂方式--------------
//function Score(math,chinese) {
// var score={
// math:math,
// chinese:chinese,
// sum:function () {
// console.log(this.math+this.chinese);
// }
// }
// return score;
//}
//
//var stu1=Score(100,80);
//stu1.sum();
// ---------04.构造函数/05.构造函数+原型-------------
// 创建构造函数,把事务共有的属性和方法提炼出来,构造函数名字,首字母大写
function Score(math,chinese) {
this.math=math;
this.chinese=chinese;
// this.sum=function () {
// console.log(this.math+this.chinese);
// }
this.zonghe={
wuli:80,
huaxue:80,
shengwu:80
}
}
/*
*实例化对象分为三步:
* ①创建空对象;
* ②构造函数内部的this
* 指向当前实例化对象
* ③执行构造函数代码
* */
// 每一个构造函数都有一个prototype属性/对象。该属性的所有方法都能被构造函数继承
Score.prototype.sum=function () {
console.log(this.math+this.chinese);
}
// 实例对象:具体的每一个事物,new+构造函数
var s1=new Score(100,90);
console.log(s1.math); //100
console.log(s1.chinese); //90
s1.sum(); //190
var s2=new Score(89,90);
// 方法类的一般执行的效果一般是一样,如果放在构造函数内部,会造成资源的浪费.
// sum方法在原型里面,所以每次创建对象的时候,不用开辟新空间。sum不属于自有属性,属于继承过来的
console.log(s1.sum==s2.sum); //true
//hasOwnProperty()判断是自有属性还是继承的
console.log(s1.hasOwnProperty('sum')); //false 不是自有属性
console.log(s1.hasOwnProperty('math')); //true 自有属性
</script>
</body>
</html>
12 构造函数+原型相关问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// <!--创建构造函数,把事务共有的属性和方法提炼出来.构造函数名字,首字母大写-->
function Score(math,chinese) {
this.math=math;
this.chinese=chinese;
this.zonghe={
wuli:90,
huaxue:80,
shengwu:80
}
this.sum=function () {
console.log('这是总成绩');
}
}
Score.prototype.sum=function () {
console.log(this.math+this.chinese);
}
var s1=new Score(100,80);
var s2=new Score(90,79);
// 如果自身有该方法,就不会继承了.如果想要修改构造函数的方法,找到构造函数
// s1.sum();
// 相当于修改了s1 其余实例对象的该属性不会改变
s1.sum=function () {
console.log('这是修改之后的方法');
}
// 如果是方法在原型属性里面,可以通过该方式修改
Score.prototype.sum=function () {
console.log('这是修改之后的方法');
}
s1.__proto__.sum=function () {
console.log('这是修改之后的方法');
}
// 构造函数的prototype属性等价于实例对象的_proto_属性
console.log(s1.__proto__==Score.prototype);
// 实例对象.constructor指向构造函数
console.log(s1.constructor==Score);
s2.sum();
// 判断是否是自有属性
console.log(s1.hasOwnProperty('sum'));
// ?????
// console.log(Score.prototype.__proto__==Object.prototype);
console.log(Score.prototype.__proto__);
console.log(Object.prototype.__proto__);
</script>
</body>
</html>
13 constructor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function Product(title,price) {
this.title=title;
this.price=price;
}
// 新增,不会修改原来的属性
// Product.prototype.buy=function () {
// console.log('购买了');
// }
// 重写prototype,丢失了constructor
Product.prototype={
// constructor:Product,
buy:function () {
console.log('购买了!');
},
joinshop:function () {
console.log('加购物车');
}
}
// var stu={
// name:'zs'
// }
相当于新增
// stu.age=12;
重写丢失了name属性
// stu={
// age:12
// }
console.log(Product.prototype); //Object
var p1=new Product('小球',100);
p1.buy(); //购买了
console.log(p1.hasOwnProperty('constructor')); //false
// 实例对象的constructor不一定会指向构造函数,重写之后如果不补,就会丢失
console.log(p1.constructor==Product); //false
// instanceof判断实例对象是否是某个构造函数的实例对象
console.log(p1 instanceof Product); //true
</script>
</body>
</html>
14 get和set
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
var circle={
r:10,
// get 方法名 用来获取值
get acr(){
return Math.PI*this.r*this.r;
},
// set 方法名 用来设置值
set acr(value){
this.r=value;
}
}
// 如果赋值,默认调用就是set方法
circle.acr=89; //如果还有这行,结果就是:24884.555409084755 [先赋值,然后再计算,此时r为89]
// 如果不赋值,默认调用就是get方法
console.log(circle.acr); //如果仅有这行,结果就是:314.1592653589793
</script>
</body>
</html>
15 属性特征
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>09</title>
</head>
<body>
<script>
var stu={
name:'zs',
age:12
}
// 遍历属性
// for(var i in stu){
// console.log(i);
// }
// 修改属性
// stu.salary=10000;
Object.defineProperty(stu,'salary',{
value:'8000',
// 值是否可以修改,不能用重新配置的方式修改
writable:true,
// 是否可以遍历/枚举
enumerable:false,
// 是否可以重新配置/定义
configurable:true
});
stu.salary='1000';
// Object.defineProperty(stu,'salary',{
// value:'10000',
// });
console.log(stu.salary);
// stu.salary=10000
//
// for(var i in stu){
// console.log(i);
// }
</script>
</body>
</html>
16 原型链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原型链</title>
</head>
<body>
<script>
// isPrototypeof()方法
// 判断一个prototype对象是否存在于另一个对象的原型链中
// 返回值true:是;返回值false:否
// 原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或者方法,就会去关联的prototype那里寻找
// 如果prototype没有,就会去prototype关联的前辈prototype那里寻找,如果没有,依次向上寻找
// 依此类推,知道prototype...prototype为undefined,从而形成了所谓的“原型链”
// a.isPrototype(b)方法 判断a是否是b的父级
// 判断一个prototype对象是否存在于另一个对象的原型链中
var car = {color:'red'};
// 通过car创建了car1 car的属性car1也可以有
var car1 = Object.create(car);
var car11 = Object.create(car1);
console.log(car1.isPrototypeOf(car11)); //true
console.log(car11.isPrototypeOf(car11)); //false
console.log(car.isPrototypeOf(car11)); //true
//car是实例对象,没有prototype,而Object是构造函数,才可以这样写
console.log(Object.prototype.isPrototypeOf(car11)); //true
</script>
</body>
</html>
17 es6
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// <!--es6中关于类的定义,只是一个"语法糖"(可有可无),es6中关于类定义,es5都可以实现-->
// 定义score类
class Score{
// 方法与方法之间不用加标点
// constructor方法内部一般放置属性,放置在constructor内部的方法,是自有
constructor(math,chinese){
this.math=math;
this.chinese=chinese;
this.sum=function () {
console.log('自有计算和的方法');
}
}
// 书写自己的方法,该方法放置在Score.prototype原型内部
sum(){
console.log(this.math+this.chinese);
}
average(){
console.log('这是平均分数');
}
}
var s1 = new Score(100,80);
var s2 = new Score(10,60);
// s1.sum();
s1.__proto__.sum=function () {
console.log('这是总成绩');
}
// s1.sum();
console.log(s1.sum==s2.sum); //true
console.log(s1.hasOwnProperty('sum')); //false
console.log(s1.hasOwnProperty('math')); //true
console.log(s1.hasOwnProperty('constructor')); //false??
console.log(s1 instanceof Score); //true
console.log(s1.__proto__==Score.prototype); //true
console.log(s1.constructor==Score); //true
console.log(Score.prototype.isPrototypeOf(s1)) //true
</script>
</body>
</html>
18 constructor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Product{
// 类内部,必须要有constructor。如果没有显示定义的话,生成实例对象的时候,会隐式生成constructor
// constructor默认返回的是实例对象,完全可以指定返回另一个对象
constructor(title){
return new Array(10);
this.title
}
buy(){
console.log('hello');
}
}
// p1是数组
let p1 = new Product();
// p1.buy();
console.log(p1 instanceof Array); //true
p1.push(1,2,3,4);
// return创建了数组,后面有的一堆如这里的buy方法都不能用了
console.log(p1); //(14) [empty × 10, 1, 2, 3, 4]
console.log(p1.constructor); //ƒ Array() { [native code] }
</script>
</body>
</html>
19 继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Person{
constructor(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
login(){
console.log('登录了。。。');
}
}
// es6中通过extends关键字实现继承
class Student extends Person{
constructor(name,age,sex,id){
// super()呈递共有的数据,相当于把共有的属性,复制过来
super(name,age,sex);
this.id=id;
}
login(){
console.log('学生登陆了。。。');
}
}
var s1 = new Student('zs',12,'男',2020);
console.log(s1);
console.log(s1.hasOwnProperty('name'));
console.log(s1.hasOwnProperty('login'));
s1.login();
console.log(Person.prototype.isPrototypeOf(s1));
console.log(Student.prototype.isPrototypeOf(s1));
console.log(Object.prototype.isPrototypeOf(s1));
</script>
</body>
</html>
20 super
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Person{
login(){
console.log('登录了...');
}
}
// es6中通过extends关键字实现继承
class Student extends Person{
constructor(id){
// super相当于复制constructor里面的东西,没有东西也要使用
super();
// 子类里面使用this之前必须调用super方法.子类实例对象的构建是在父类实例的基础上
// 调用完了super方法以后,返回父类实例,才可以使用this
this.id=id;
}
// 当自己有同一方法时,优先使用自己的方法
login(){
console.log('学生登录了...');
}
}
var s1=new Student();
s1.login();
</script>
</body>
</html>
21 get和set
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Circle{
constructor(r){
this.r=r;
}
// 获取值
get acr(){
return Math.PI*this.r*this.r;
}
// 设置值
set acr(value){
this.r=value;
}
}
var c=new Circle(100);
// 如果赋值的话,调用set acr方法;
c.acr=98;
// 如果不赋值,调用get acr方法
console.log(c.acr);
</script>
</body>
</html>
22 静态属性和静态方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
class Person{
constructor(){
}
// 静态方法 定义的时候,方法名字前面加static
// 使用的时候,直接通过类调用。静态方法可以被继承
static getId(){
console.log('getId');
}
}
// 直接通过类名定义的属性.属于静态属性,只能通过类调用,可以继承
Person.className='xxxx';
class Student extends Person{
}
var p = new Person();
// p.getId();实例对象不能使用静态方法
Person.getId(); //getId
console.log(Person.className); //xxxx
Student.getId(); //getId
console.log(Student.className); //xxxx
console.log(p.className); //undefined
</script>
</body>
</html>
23 私有方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>私有方法</title>
</head>
<body>
<script>
class Product{
go(){
this._buy();
}
// 方法名前面加下划线,变成私有方法,私有方法默认只能在类的内部使用
_buy(){
console.log('buy');
}
}
var p=new Product();
p._buy(); //buy
p.go(); //buy
</script>
</body>
</html>