# HTML+CSS+JS
**Repository Path**: SeteVII/html-css-js
## Basic Information
- **Project Name**: HTML+CSS+JS
- **Description**: html+css+js
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-10-11
- **Last Updated**: 2023-10-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# HTML+CSS
## 水平垂直居中
### flex弹性布局
```css
.father {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.son{
...
}
```
### absolute+margin:auto
```css
.father {
position: relative;
}
.son {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
```
### absoulte+transform
```css
.father {
position: relative;
}
.son {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
```
### grid布局
```css
.father {
display: grid;
align-items: center;
justify-content: center;
width: 200px;
height: 200px;
border: 1px solid;
}
```
### table-cell
```css
.father {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.son {
display: inline-block;
}
```
## BFC
BFC:块格式化上下文,是一块独立的渲染区域,内部元素不会影响外部元素。
**创建BFC的条件**
- 根元素:body
- 元素设置浮动:float除none以外的值
- 元素设置绝对定位:position(absolute、fixed)
- display:inline-block、table-cell、flex等
- overflow:hidden、auto、scroll
**BFC特点**
- 垂直方向上,自上而下的排列,和文档流的排列方式一致
- 在BFC中上下相邻的两个容器的margin会重叠
- 计算BFC的高度时,需要计算浮动元素的高度
- BFC区域不会与浮动的容器发生重叠
- BFC是独立的容器,容器内部的元素不会影响外部元素
- 每个元素的左margin值和容器的左border相接触
**BFC的作用**
- **解决margin的重叠问题**:由于BFC是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个BFC,就解决了margin重叠的问题
- **解决高度塌陷的问题**:在子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。解决这个问题,只需要把父元素变成一个BFC。常用的办法给父元素设置`overflow:hidden`
- **创建自适应两栏布局**:左边宽度固定,右边宽度自适应
```html
```
```css
.left {
width: 100px;
height: 200px;
background: salmon;
float: left;
}
.right {
height: 300px;
background: seagreen;
overflow: hidden;
}
```
# js基础
## js输出
```js
// 控制浏览器弹出一个警告窗
alert('123');
// 输出内容到页面上
document.write('345');
// 输出内容到控制台
console.log('456');
```
## js事件
```html
点击链接
点击链接
```
# 强制类型转换
强制类型转换
指将一个数据类型强制转换为其他的数据类型
类型转换主要指,将其他的数据类型,转换为String Boolean Number
将其他的数据类型转换为String
方式一:
- 调用被转类型的toString()方法
- 该方法不会影响到原变量的值,它会将转换的结果返回
- null和undefined没有toString()方法
方式二:
- 使用String()函数
- 使用String()函数做强制转换时,
对于Number和Boolean实际上就是调用的toString()方法
对于null和undefined,就不会调用toString()方法.它会将null转换为'null',将undefined转换为'undefined'
# 数据类型检测
## typeof
typeof可以区分object和function
数组(日期/正则)、对象、null会被判断为object(null是因为null的二进制全为0,000开头的是对象)
```js
console.log(typeof 2); //number
console.log(typeof true); //boolean
console.log(typeof 'str'); //string
console.log(typeof []); //object
console.log(typeof function () { }); //function
console.log(typeof {}); //object
console.log(typeof undefined); //undefined
console.log(typeof null); //object
```
## instanceof
instanceof判断对象的类型,只能判断引用数据类型,用来测试一个对象在其原型链中是否存在一个构造函数prototype属性
内部运行机制:判断在其原型链中能否找到该类型的原型
功能:判断两个对象是否属于实例关系
缺点:无法判断某一对象具体属于哪种类型
```javascript
console.log(2 instanceof Number); //false
console.log(true instanceof Boolean); //false
console.log('str' instanceof String); //false
console.log([] instanceof Array); //true
console.log(function () { } instanceof Function); //true
console.log({} instanceof Object); //true
```
如果`instanceof`想要检测基本数据类型,可`new`一个包装类型
```javascript
const num1=new Number(123);
console.log(num1 instanceof Number);//true
console.log(num1 instanceof Object);//true
const str1=new String("abcdef");
console.log(str1 instanceof String);//true
console.log(num1 instanceof Object);//true
```
## constructor
功能:`constructor`是原型`prototype`的一个属性,可以通过一个对象的`constructor`属性比对对象的数据类型
缺点:`null`和`undefined`没有`constructor`
> 作用:1.判断数据的类型 2.对象实例通过constructor对象访问它的构造函数
```js
console.log((2).constructor === Number); //true
console.log((true).constructor === Boolean); //true
console.log(('str').constructor === String); //true
console.log(([]).constructor === Array); //true
console.log((function () { }).constructor === Function); //true
console.log(({}).constructor === Object); //true
```
如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了
```js
function Fn() { }
Fn.prototype = new Array()
var f1 = new Fn()
console.log(f1.constructor === Fn); //false
console.log(f1.constructor === Array); //true
```
## Object.prototype.toString.call
toString()是Object的原型方法,调用该方法,默认返回当前对象的[[Class]]
**obj.toString()**
Object自带方法,用于将对象转换为字符串
undefined、null对象没有toString方法
```js
//Number
const num = 123;
console.log(num.toString()); // '123'
console.log((123).toString()); // '123'整数必须赋值给变量后或放在括号中再调用toString
console.log(1.23.toString()); // '1.23'小数可直接调用
console.log(NaN.toString()); // 'NaN'
console.log(Infinity.toString()); // 'Infinity'
console.log(-Infinity.toString()); // -Infinity根据运算符优先级关系,先执行toString再将String转为Number
//数字通过toString进行进制转换
console.log(num.toString()); // '123'默认转为十进制
console.log(num.toString(2)); // '1111011'
console.log(num.toString(8)); // '173'
console.log(num.toString(16)); // '7b'
//Array
console.log([1, 2, 3].toString()); // '1,2,3'结果与数组的join()方法相同
//Object
console.log(({}).toString()); // "[object Object]"
//Function
const func = function () { };
console.log(func.toString()); // "function(){}"
//Boolean
const t = true, f = false;
console.log(t.toString()); // 'true'返回对应字符串
console.log(f.toString()); // 'false'
```
**Object.prototype.toString.call()**
使用Object对象的原型方法toString来判断数据类型
```js
var a = Object.prototype.toString
console.log(a.call(2)); //[object Number]
console.log(a.call(true)); //[object Boolean]
console.log(a.call('str')); //[object String]
console.log(a.call([])); //[object Array]
console.log(a.call(function () { })); //[object Function]
console.log(a.call({})); //[object Object]
console.log(a.call(undefined)); //[object Undefined]
console.log(a.call(null)); //[object Null]
```
> 同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,为什么?
>
> 因为toString是Obejct的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的*toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。
# 运算符
运算符也叫操作符
通过运算符可以对一个或多个值进行计算,并获取运算结果
## typeof
typeof 就是一个运算符,可以用来获取一个值的类型,它会将该值的类型以字符串的形式返回
## 算数运算符 + - * / %
任何值和NaN做加法计算结果都是NaN
任何值 + '' 即可转换为String,调用String()函数,隐式转换
任何值做 - / * 运算时都会自动转换为Number,我们可以通过 -0 *1 /1 来将其转换为Number,隐式转换
## 逻辑运算符 &&与 ||或 !非
!非. 取反Boolean值,如果对一个非布尔值进行元素,则会将其转化为布尔值,然后再取反.利用该特点,可以将其他数据类型转换为布尔值。!!!为任意数据类型取两次非运算(一次反结果错误),来将其转换为布尔值。原理和Boolean()函数一样。
&&与。对符号两侧的值进行运算并返回结果。运算规则:两个值都为true则为true,否则为false。短路,如果第一个值为false,不会检查第二个值。
||或。对符号两侧的值进行运算并返回结果。运算规则:两个值都为false则返回false,否则为true。短路。如果第一个值为true,则不会检查第二个值。
(&& || )非布尔值的情况:
对于非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回 值。
与运算:如果两个值都为true,则返回第二个的值。如果两个值都为false,则返 第一个值。如果一个true,一个false,则返回false的值。
或运算:如果两个值都为false,则返回第二个的值。如果两个值都为true,则返 第一个值。如果一个true,一个false,则返回true的值。
## 关系运算符 > < = >= <=
非数值情况:
非数值进行比较时,会将其转换为数字然后再比较,任何值和NaN比较都为false
符号两侧都为字符串时,不会转换为数字进行比较,分别比较字符串中字符的Unicode编码
# 函数节流
在规定的时间范围内相同的操作触发多次只执行一次
```javascript
export const debounce = (fn, delay) => {
let timer = null
return function () {
let context = this, args = arguments
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, args)
timer = null
}, delay);
}
}
```
# 函数防抖
事件被触发n秒后再回调,如果在n内又被触发了,则重新计时
```javascript
export default throttle = (fn, delay = 100) => {
let timer = null
let preTime = Date.now().getTime()
return function () {
let context = this, args = arguments, nowTime = Date.now().getTime()
clearTimeout(timer)
if (nowTime - preTime >= delay) {
fn.apply(context, args)
preTime = nowTime
} else {
timer = setTimeout(() => {
fn.apply(context, args)
timer = null
}, delay);
}
}
}
```
# let
1.变量不能重复声明
2.块级作用域
3.不存在变量提升
4.不影响作用域链
# const
1.一定要赋初始值
2.一般常量使用大写
3.常量的值不能修改
4.块级作用域
5.对于数组和对象的元素的修改,不算做对常量的修改,不会报错(常量地址没有发生改变,所以不会报错)
# 解构赋值
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
```js
// 数组的解构(不常用)
const COLOR = ['red', 'green', 'yellow', 'blue'];
let [red, green, yellow, blue] = COLOR;
console.log(red); // red
console.log(green); // green
console.log(yellow); // yellow
console.log(blue); // blue
// 对象的解构(常用)
// 方法频繁调用,使用对象的解构赋值
const PERSON = {
name: 'luck',
age: 16,
sayName: function () {
console.log(PERSON.name);
}
}
let { name, age, sayName } = PERSON;
console.log(name); //luck
console.log(age); //16
console.log(sayName); //ƒ () {console.log(this.name);}
sayName(); //luck
```
# 模板字符串
引入新的声明字符串的方式[``] '' ""
```js
// 1.声明
let str1 = `我也是一个字符串嗷`;
console.log(str1, typeof str1); //我也是一个字符串嗷 string
// 2.内容中可以直接出现换行符
let str2 =
``;
console.log(str2);
{/* */}
// 3.变量拼接
let color = 'red';
let colorEst = `${color}是鲜艳的`;
console.log(colorEst); //red是鲜艳的
```
# 简化对象写法
ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
```js
let name = 'luck';
let change = function () {
console.log('luck是可爱的小狗');
}
const animal = {
name,
change,
improve() {
console.log('小狗');
}
}
console.log(animal); //{name: 'luck', change: ƒ, improve: ƒ}
// 原写法
// const animal = {
// name: name,
// change: change,
// improve: function () {
// }
// }
```
# 箭头函数
ES6允许使用箭头定义函数
箭头函数适合与this无关的回调,如定时器,数组的方法回调
箭头函数不适合与this有关的回调,如dom事件回调,对象的方法
```js
// 声明一个函数
let fn1 = function () {}
let fn2 = (a, b) => { return a + b }
let result = fn2(1, 2)
console.log(result); //3
// 1.this是静态的,this始终指向函数声明时所在作用域下的this值
function getName() { console.log(this.name); }
let getName2 = () => { console.log(this.name); }
// 设置window的对象name属性
window.name = 'luck';
const school = {
name: 'school',
}
// 直接调用
// 普通函数直接调用this指向window
// 箭头函数在全局作用域下声明的,this指向window
getName(); //luck
getName2(); //luck
// call方法调用
// 箭头函数this值是静态的,this始终指向函数在声明对象的this值
getName.call(school); //school
getName2.call(school); //luck
// 2.不能作为构造函数实例化对象
let Person = (name, age) => {
this.name = name;
this.age = age;
}
// let me = new Person('七', 23);
// console.log(me); //Person is not a constructor
// 3.不能使用arguments变量
// let fn3 = () => {
// console.log(arguments); //arguments is not defined
// }
// fn3(124)
// 4.箭头函数简写
// 1)省略小括号,当形参有且仅有一个
// 2)省略花括号,当代码体只有一条语句的时候,return必须省略,语句的执行结果就是函数的返回值
let pow = (n) => n * n;
console.log(pow(1)); //1
```
# 参数默认值
ES6允许给函数参数赋值初始值
```js
// 1.形参的初始值,具有默认值的参数,一般位置要靠后
function add(a, b, c = 0) {
return a + b + c
}
let result = add(1, 2);
console.log(result); //3
// 2.与解构赋值结合
function connect({ host = '127.0.0.1', username, password, port }) {
console.log(host); // 127.0.0.1
console.log(username); //root
console.log(password); //root
console.log(port); //3000
}
connect({
// host: '',
username: 'root',
password: 'root',
port: 3000,
})
```
# rest参数
ES6引入rest参数,用来获取函数的实参,用来代替arguments
```js
// ES5获取实参的方法(伪数组对象)
function date() {
console.log(arguments);
}
date('111', '222') //['111',,'222' callee: ƒ, Symbol(Symbol.iterator): ƒ]
```
```js
// rest参数(数组)
function date(...args) {
console.log(args);
}
date('111', '222'); //['111', '222']
// rest参数必须放在参数的最后面
function fn(a, b, ...args) {
console.log(a); //1
console.log(b); //2
console.log(...args); //3 4 5 6
}
fn(1, 2, 3, 4, 5, 6);
```
# 扩展运算符
[...] 扩展运算符能将[数组]转换为逗号分隔的[参数序列]
```js
// 声明一个数组
const color = ['red', 'green', 'blue'];
// 声明一个函数
function colors() {
console.log(arguments);
}
colors(color); // [Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ] 1个实参
colors(...color) //['red', 'green', 'blue', callee: ƒ, Symbol(Symbol.iterator): ƒ] 3个实参
```
# 扩展运算符的应用
```js
// 1.数组的合并
const color = ['red', 'green', 'blue'];
const num = ['1', '2', '3'];
const cononect = color.concat(num);
console.log(cononect); //['red', 'green', 'blue', '1', '2', '3']
const connect = [...color, ...num];
console.log(connect); //['red', 'green', 'blue', '1', '2', '3']
// 2.数组的克隆
const colors = ['red', 'green', 'blue'];
const clone = [...color];
console.log(clone); //['red', 'green', 'blue']
// 3.将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
console.log(divs); //NodeList(3) [div, div, div] Object
console.log([...divs]); //[div, div, div] Array
```
# Symbol
```js
// 创建symbol
let s = Symbol();
console.log(s, typeof s); //Symbol() 'symbol'
let s2 = Symbol('seven');
console.log(s2); //Symbol(seven)
let s3 = Symbol('seven');
console.log(s2 == s3); //fasle
// Symbol.for创建
let s4 = Symbol.for('seven');
console.log(s4, typeof s4); //Symbol(seven) 'symbol'
// 不能与其他数据进行运算
// let result = s + 100; //Cannot convert a Symbol value to a number
// let result = s + '100'; //Cannot convert a Symbol value to a string
```
# Symbol创建对象属性
```js
// 向对象中添加方法
let game = {
name: '闪耀暖暖',
}
// 声明一个对象
let methods = {
up: Symbol(),
down: Symbol(),
}
game[methods.up] = function () {
console.log('向上');
}
game[methods.down] = function () {
console.log('向下');
}
console.log(game); //{name: '闪耀暖暖', Symbol(): ƒ, Symbol(): ƒ}
let youxi = {
name: '狼人杀',
[Symbol('say')]: function () {
console.log('我可以发言');
}
}
console.log(youxi); //{name: '狼人杀', Symbol(say): ƒ}
```
# 迭代器
Iteartor 是一种接口(对象的一个属性),为各种不同的数据结构提供统一的访问机制
遍历操作
```js
// 声明一个数组
let color = ['green', 'blue', 'red', 'yellow'];
// 使用for...of遍历数组
for (let v of color) {
// green
// blue
// red
// yellow
console.log(v);
}
// 创建一个指针对象,指向当前数据结构的起始位置
// 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
// 接下来不断调用next方法,指针一直往后移动移动,直到只想最后一个成员
// 每调用next方法返回一个包含value和done属性的对象
console.log(color); //Symbol(Symbol.iterator): ƒ values()
let iterator = color[Symbol.iterator]();
console.log(iterator); //Array Iterator {} next: ƒ next()
console.log(iterator.next()); //{value: 'green', done: false}
console.log(iterator.next()); //{value: 'blue', done: false}
console.log(iterator.next()); //{value: 'red', done: false}
console.log(iterator.next()); //{value: 'yellow', done: false}
console.log(iterator.next()); //{value: 'undefined', done: true}
```
# 生成器函数
生成器就是一个特殊的函数
异步编程 纯回调函数 node fs ajax mongodb
生成器是对异步编程的一个解决方案
```js
// function* gen() {
// console.log('hello generator');
// }
// let iterator = gen();
// console.log(iterator); //gen {}
// 调用next()方法运行
// iterator.next(); //hello generator
// yield函数代码的分隔符
function* gen() {
yield '一直没有耳朵';
yield '一直没有眼睛';
// console.log(333);
yield '真奇怪';
// console.log(444);
}
let iterator = gen();
console.log(iterator); //gen {}
console.log(iterator.next()); //{value: '一直没有耳朵', done: false}
console.log(iterator.next()); //{value: '一直没有眼睛', done: false}
console.log(iterator.next()); //{value: '真奇怪', done: false}
console.log(iterator.next()); //{value: 'undefined', done: true}
// 遍历
// for (let v of gen()) {
// // 一直没有耳朵
// // 一直没有眼
// // 真奇怪
// console.log(v);
// }
```
# 生成器函数参数
```js
function* gen(arg) {
console.log(arg); //aaa
let one = yield 1;
console.log(one); //BBB
let two = yield 2;
console.log(two); //CCC
let three = yield 3;
console.log(three); //DDD
let four = yield 4;
console.log(four); //EEE
}
let iterator = gen('aaa'); //传给arg
// ?next方法可以传入实参,这个实参就是整个yield语句的返回结果
console.log(iterator.next('AAA'));
console.log(iterator.next('BBB')); //传给第一个yield
console.log(iterator.next('CCC')); //传给第二个yield
console.log(iterator.next('DDD')); //传给第三个yield
console.log(iterator.next('EEE')); //传给第四个yield
```
# Promise
promise是ES6引入的异步编程的新解决方案,
Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
```js
// 实例化Promise对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// let data = '数据库中的用户数据'
// #resolve 成功
// resolve(data)
let err = '数据读取失败';
// #reject 失败
reject(err)
}, 1000);
})
// 调用promise对象的then方法
p.then(value => { //#成功
console.log(value); //数据库中的用户数据
}, reason => { //#失败
console.log(reason); //数据读取失败
})
```
# Promise的then方法
```js
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
}, 1000);
});
// 调用then方法 then方法的返回结果是Promise对象,对象状态由回调函数的执行结果决定
// 1.如果回调函数中返回的结果是非Promise类型的属性,状态为成功,返回值为对象成功的值
const result = p.then(value => {
console.log(value); //用户数据
// 非Promise类型的属性
// return 'wer'; //: "fulfilled" : "wer"
// 是Promise对象
// return new Promise((resolve, reject) => {
// resolve('ok') //: "fulfilled" < value >: "ok"
// })
// 抛出错误
throw '出错啦'; //: "rejected" : "出错啦"
}, reason => {
console.log(reason);
})
console.log(result);
// 链式调用
// p.then()
```
# Promise读取文件
```js
const { rejects } = require('assert');
const fs = require('fs');
// 调用方法读取文件
// fs.readFile('README.md', (err, data) => {
// if (err) throw err;
// console.log(data);
// console.log(data.toString());
// });
// 使用promise封装
const p = new Promise((resolve, reject) => {
fs.readFile('README.md', (err, data) => {
if (err) reject(err); //失败
resolve(data); //成功
})
});
p.then(value => {
console.log(value.toString());
}, reason => {
console.log(reason);
})
// 失败的回调
// p.catch(reason => {
// console.log(reason);
// })
```
# Promise封装ajax
```js
// 接口地址:https://api.apiopen.top/getJoke
// 1.创建对象
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', "https://api.apiopen.top/getJoke");
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status >= 200 & xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
})
p.then(value => {
console.log(value);
}, reason => {
console.log(reason);
})
```
# 集合
ES6提供的新的数据结构 Set
类似于数组,但成员的值都是唯一的,集合实现了iterator接口,
可以使用扩展运算符和for...of进行遍历
```js
// 声明一个set
let s = new Set();
let s2 = new Set(['大事', '小事', '好事', '小事']);
console.log(s, typeof s); //Set [] object
console.log(s2); // Set(3) [ "大事", "小事", "好事" ]
// 元素个数
console.log(s2.size); //3
// 添加新的元素
s2.add('喜事')
console.log(s2); // Set(4) [ "大事", "小事", "好事", "喜事" ]
// 删除元素
s2.delete('喜事');
console.log(s2); //Set(3) [ "大事", "小事", "好事" ]
// 检测
console.log(s2.has('好事')); //true
// 清空
// s2.clear();
// console.log(s2); //Set []
// 遍历
for (const item of s2) {
// 大事
// 小事
// 好事
console.log(item);
}
```
# Map
ES6提供的新的数据结构 Map
类似于对象,也是键值对的集合,但是键的范围不包括字符串,合作类型的值包括对象都可以当做键,集合实现了iterator接口,
可以使用扩展运算符和for...of进行遍历
```js
// 声明一个set
let o = new Map();
// 添加元素
o.set('name', 'luck');
o.set('change', function () {
console.log('我们可以改变你');
})
console.log(o, typeof o); //Map(2) {size: 2, name => luck, change => ƒ ()} object
let key = {
color: 'red'
}
o.set(key, ['北京', '上海']);
console.log(o); //Map(3) {size: 3, name => luck, change => ƒ (), {color: 'red'} => (2) ['北京', '上海', …]}
// 元素个数
console.log(o.size); //3
// 删除元素
o.delete('name');
console.log(o); //Map(2) {size: 2, change => ƒ (), {color: 'red'} => (2) ['北京', '上海', …]}
// 读取
console.log(o.get('change')); //ƒ () {console.log('我们可以改变你');}
// 清空
// o.clear();
// console.log(o); //Map(0) {size: 0}
// 遍历
for (const item of o) {
//['change', ƒ] ƒ () {\r\n console.log('我们可以改变你');\r\n}
//['北京', '上海']
console.log(item);
}
```
# Class
```js
// ES5
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
// 添加方法
Phone.prototype.call = function () {
console.log('我可以打电话');
}
// 实例化对象
let huawei = new Phone('华为', 5888);
huawei.call(); //我可以打电话
console.log(huawei); //Phone {brand: '华为', price: 5888}
```
```js
// 手机
// ES6
class Phone {
// 构造方法 constructor
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 方法,必须写这种语法
call() {
console.log('我可以打电话');
}
}
let huawei = new Phone('huawei', 8999);
huawei.call()
console.log(huawei); //Phone {brand: 'huawei', price: 8999}
```
# Class的静态成员
```js
// ES5
function Phone(){}
Phone.name = '手机'; //静态成员 属于类不属于实例对象
Phone.change = function () {
console.log('我可以听歌');
}
Phone.prototype.size = '5.5inch'
// debugger;
let nokia = new Phone();
console.log(nokia.name); //undefined
console.log(nokia.size);
// nokia.change(); //发生异常: TypeError: nokia.change is not a function
```
```js
// ES6
// static 属于类不属于实例对象
class Phone {
// 静态属性
static name = '手机';
static change() {
console.log('我可以改变世界');
}
}
debugger;
let nokia = new Phone();
console.log(Phone.name); //手机
console.log(nokia.name); //undefined
Phone.change(); //我可以改变世界
```
# Class的get和set
```js
class Phone {
get price() {
console.log('价格属性被读取了');
return 'get读取'
}
// set必须有一个形参
set price(newVal) {
console.log('价格属性被修改了');
}
}
let s = new Phone();
console.log(s.price); //价格属性被读取了 get读取
s.price = 3400; //价格属性被修改了
```
# Class继承
```js
// ES5
// 手机
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
// 添加方法
Phone.prototype.call = function () {
console.log('我可以打电话');
}
// 智能手机
function SmarkPhone(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
// 设置子级构造函数的原型
SmarkPhone.prototype = new Phone;
SmarkPhone.prototype.constructor = SmarkPhone;
// 声明子类方法
SmarkPhone.prototype.photo = function () {
console.log('我可以拍照');
}
let huawei = new SmarkPhone('华为', 5888, 'black', '5.5inch');
console.log(huawei); //SmarkPhone {brand: '华为', price: 5888, color: 'black', size: '5.5inch'}
```
```js
// ES6
class Phone {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log('我可以打电话');
}
}
class SmarkPhone extends Phone {
constructor(brand, price, color, size) {
super(brand, price);
this.color = color;
this.size = size;
}
photo() {
console.log('我可以拍照');
}
// 子类重写
call() {
console.log('我可以视频通话');
}
}
let xiaomi = new SmarkPhone('小米', 7999, '玫瑰金', '5.5inch');
console.log(xiaomi); //SmarkPhone {brand: '小米', price: 7999, color: '玫瑰金', size: '5.5inch'}
xiaomi.call(); //我可以视频通话
xiaomi.photo();//我可以拍照
```