1.严格模式
- 使用严格模式,可以在函数内部进行较为严格的全局和局部的错误条件检查
- 严格模式的编译指示,"use strict"
- 创建全局变量,未声明变量,非严格模式下为创建全局变量;严格模式下为抛出ReferenceError
- 对变量调用delete操作符,删除变量,非严格模式下为静默失败;严格模式下为抛出ReferenceError
- 操作对象情况下:a,只读属性赋值会抛出TypeError;b,对不可配置的属性使用delete操作符会抛出TypeError;c,为不可扩展的对象添加属性会抛出TypeError。
- 重名属性情况:a,非严格模式下没有错误,以第二个属性为准;b,严格模式下会抛出语法错误。
- 函数参数必须唯一,重名参数,在非严格模式下没有错误,只能访问第二个参数;严格模式下,会抛出错误。
function funValue(value) {
value="dada";
alert(value); // dada
alert(argument[0]); // 非严格模式:dada
// 严格模式模式 dadaqianduan
}
funValue('dadaqianduan');
复制代码
- 访问arguments.callee和arguments.caller,在非严格模式下没有问题,严格模式下抛出TypeError。
2.Class基础语法
在JavaScript当中如何声明一个类?如何定义类中的方法?如何实例化对象?
我们来看看下面的代码示例:
// es5
let dada = function(type) {
this.type = type
}
dada.prototype.study = function() {
console.log('魔王哪吒');
}
let da1 = new dada('程序员')
let da2 = new dada('It')
da1.constructor.prototype.study = function() {
console.log('dadaqianduan');
}
da1.study()
复制代码
JavaScript constructor
属性
定义和用法
constructor
属性返回对创建此对象的数组函数的引用。
语法
object.constructor
constructor
是一种用于创建和初始化class
创建的对象的特殊方法。
// es6
class Da {
constructor(name) { // 构造函数内写属性
this.name = name;
}
eat() { // 构造函数外写方法
console.log('i eat')
}
}
const da1 = new Da('da1');
console.log(da1.name); // da1
console.log(da1);
复制代码
- 一个类中只能有一个名为“constructor"的方法,出现多次构造函数constructor方法会抛出一个SyntaxError错误
- 在一个构造方法中可以使用super来调用一个父类的构造方法
- 如果没有指定一个构造函数方法constructor方法,就会使用一个默认的构造函数
3.类的属性Setter和Getter
var daObj = {
get val() {
return ;
},
set val(value) {
}
}
复制代码
get:
var da = {
a: 1,
get val(){
return this.a + 1;
}
}
console.log(da.val);//2
da.val = 100;
console.log(da.val);//2
class Da {
constructor(type) {
this.type = type
}
get age() {
return 1
}
set age(val) {
this.realAge = val
}
eat() {
console.log('i am eat')
}
}
let da1 = new Da('da1')
console.log(da1.age)
da1.age = 1
console.log(da1.realAge)
复制代码
class Da {
constructor(type, age) {
this.type = type
this.age1 = age
}
get age() {
return this._age
}
set age(val) {
this._age = val
}
}
复制代码
利用set/get实现对element.innerHTML封装
class myHTMLElement {
constructor(element) {
this.element = element
}
get html() {
return this.element.innerHTML
}
set html(value) {
this.element.innerHTML = value
}
}
复制代码
设置一个闭包,通过一定的规则来限制对它的修改:
let myName = 'dada'
class Da {
constructor(type) {
this.type = type
}
get name() {
return myName
}
set name(val) {
myName = val
}
}
复制代码
4.静态方法
在es5中实现的静态方法:
let Da = function (type) {
this.type = type
this.eat = function() {
console.log('i eat')
}
}
Da.study = function(book) {
console.log('i book');
}
复制代码
let Da = function(type) {
this.type = type
}
Da.prototype.eat = function() {
Da.walk()
console.log('i am')
}
Da.walk = function(){
console.log('walk')
}
let da1 = new Da('da1')
da1.eat()
// walk
// i am
复制代码
静态方法在你的实例化对象是找不到的
在es6中的静态方法,标记static
5.如何继承一个类
在es5中的继承:
// 定义一个父类
let Da = function(type) {
this.type = type
}
// 定义方法
Da.prototype.eat = function() {
console.log('i am')
}
// 定义静态方法
Da.study = function(book) {
console.log('i study')
}
// 定义子类
let Da1 = function() {
// 初始化父类
Da.call(this, 'da1');
this.run = function() {
console.log('i run')
}
}
// 继承
Da1.prototype = Da.prototype
复制代码
在es6中的继承
class Da {
constructor(type) {
this.type = type
}
eat() {
// Da.walk();
console.log('i eat')
}
static walk(){
console.log('i walk')
}
}
class da extends Da {
// 构造函数
//constructor (type) {
//super(type)
//}
run() {
console.log('i run')
}
}
let da1 = new da('da1')
复制代码
6.面向对象编程Class
类的声明,属性,方法,静态方法,继承,多态,私有属性
// 类的声明
let Da = function(type) {
this.type = type
this.eat = function() {
console.log('i eat');
}
}
let da = new Da('da');
复制代码
// prototype
let Da = function(type) {
this.type = type
}
Da.prototype.eat = function() {
console.log('i eat')
}
let da1 = new Da('da1')
复制代码
es6中的Class
class Da {
// 构造函数
constructor(type) {
this.type = type
}
// 方法
walk() {
console.log('i walk')
}
}
let da = new Da('da');
// console.log(typeof Da); function
复制代码
7.函数参数的默认值
函数参数是从左到右解析,如果没有默认值会被解析成
undefined
// 参数默认值
function da (x,y,z) {
}
function sum() {
let num = 0
Array.prototype.forEach.call(arguments, function(item){
num += item * 1
})
Array.from(arguments).forEach(function(item){
num += item * 1
})
return num
}
复制代码
// 不确定
function sum(...nums) {
let num = 0
nums.forEach(function(item){
num += item * 1
})
return num
}
console.log(sum(1,2,3,4,5))
复制代码
function sum () {
let num = 0
Array.prototype.forEach.call(arguments, function (item) {
num += item * 1
})
return num
}
function sum (...nums) {
let num = 0
nums.forEach(function (item) {
num += item * 1
})
return num
}
复制代码
8.es6箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
() => {}
// function Da() {}
// let da = function() {}
let da = () => {
console.log('hello')
}
da()
let da = name => {}
复制代码
const materials = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
console.log(materials.map(material => material.length));
// expected output: Array [8, 6, 7, 9]
复制代码
拓展
判断函数有几个参数
- 在 ES5 中可以在函数体内使用 arguments 来判断。
- 在 ES6 中可以借助 Function.length 来判断。(统计第一个默认参数前面的变量数)
9.JavaScript中的三个点(…)
JavaScript当中,函数的参数前面有三个点,代表什么呢?我们看下代码示例:
function myFunc(a, b, ...args) {
console.log(a); // 22
console.log(b); // 98
console.log(args); // [43, 3, 26]
};
myFunc(22, 98, 43, 3, 26);
复制代码
function myFunc(x, y, ...params) { // used rest operator here
console.log(x);
console.log(y);
console.log(params);
}
var inputs = ["a", "b", "c", "d", "e", "f"];
myFunc(...inputs); // used spread operator here
// "a"
// "b"
// ["c", "d", "e", "f"]
复制代码
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
复制代码
10.Object Property
JS中对象的属性定义,代码示例如下:
let x = 'da1';
let y = 'da2';
let obj = {
x,
y
}
console.log(obj);
// 结果
{x:'da1',y:'da2'}
复制代码
let x=1; let y=2; let z=3
let obj = {
'x': x,
y,
[z+y]: 4,
* hello() { // 异步
console.log('dada')
}
}
// function* functionName() {}
obj.hello()
复制代码
11.Set数据结构
Set存储的成员不允许的重复的(它类似于数组)
Set 本身是一个构造函数,用来生成 Set 数据结构。
const s = new Set();
[2, 3, 5].forEach(x => s.add(x));
Set 函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化
const set = new Set([1, 2, 3, 4, 4]);
复制代码
实现数组去重
var arr = [1,1,2,2,3,3]; // step1:数组转集合
var s = new Set(arr); // 已经去掉重复值,当前不是数组,而集合
s.size; // 3
// step2:集合转数组
console.log([...s]); // 1,2,3;
// Array.form 方法可以将 Set 结构转为数组
const items = new Set([1, 2, 3]);
const arr = Array.from(items);
function dada(array) {
return Array.from(new Set(array));
}
dada([1, 1, 2])
复制代码
Set的遍历
keys()
:返回键名
的遍历器values()
:返回键值
的遍历器entries()
:返回键值对
的遍历器forEach()
:使用回调函数遍历每个成员
操作方法
add(value)
:添加某个值
,返回Set结构本身。delete(value)
:删除某个值
,返回一个布尔值,表示删除是否成功。has(value)
:返回一个布尔值
,表示该值是否为Set的成员。clear()
:清除所有成员
,没有返回值。
let set = new Set([1, 2, 3, 4, 4]);
// 添加数据
let addSet = set.add(5);
console.log(addSet); // Set(5) {1, 2, 3, 4, 5}
// 删除数据
let delSet = set.delete(4);
console.log(delSet); // true
// 查看是否存在数据 4
let hasSet = set.has(4);
console.log(hasSet); // false
// 清除所有数据
set.clear();
console.log(set); // Set(0) {}
复制代码
实现并集(Union)、交集(Intersect)和差集(Difference)
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2, 1]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {1, 2, 3}
// 差集
let difference = new Set([...b].filter(x => !a.has(x)));
// Set {4}
复制代码
12.Map数据结构
JS当中的哈希表,使用方法如下:
let map = new Map()
map.set(1, 2)
map.set(3, 4)
map.set(1, 3)
console.log(map)
创建
var da = new Map();
var jeskson = {};
遍历
da.forEach(function(value,key,map){}
长度
da.size
删除
//da.delete() 删除key,全部清楚da.clear()
新增
da.set(key,value)
da.has(查索引值)
da.forEach((value,key) =>{
})
for( let [key, value] of map){}
// let map = new Map( [[1,2], [3,4]] )
map的key任意都可以
let o = function() {
console.log('o')
}
map.set(o, 3)
console.log(map.get(o)); // 3
复制代码
// map.js
var Dictionary = function() {
var items = {};
// 检查键
this.has = function(key) {
return key in items;
}
// 添加键值对
this.set = function(key, value){
items[key] = value;
}
// 通过键移除元素
this.delete = function(key) {
if(this.has(key)){
delete items[key]
return true
}
return false
}
// 键获取值
this.get = function(key){
return this.has(key) ? items[key] : undefined;
}
// 列表返回字典值
this.values = function() {
var values = [];
for(var k in items) {
if(this.has(k)) {
values.push(items[k])
}
}
return values;
}
// 获取全部键名
this.keys = function() {
return Object.keys(items);
}
// 获取私有变量items
this.getItems = function() {
return items;
}
}
复制代码
Map数据结构,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
13.Object.assign(对象的拷贝)
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
> Object { a: 1, b: 4, c: 5 }
> Object { a: 1, b: 4, c: 5 }
复制代码
语法
Object.assign(target, ...sources)
复制代码
参数
target
复制代码
目标对象
sources
复制代码
源对象
返回值
目标对象。
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
复制代码
- Object.assign()拷贝的是(可枚举)属性值
- Object.assign方法的第一个参数是目标对象,后面的参数都是源对象
- 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
- 由于undefined和null无法转成对象,所以如果它们作为参数,就会报错
- 如果undefined和null不在首参数,就不会报错
- 如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用(这个对象的任何变化,都会反映到目标对象上面。)
Object.assign(undefined) // 报错
Object.assign(null) // 报错
let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source)
// { foo: 1 }
复制代码