function father () {
let num = 66;
// 闭包:返回一个函数,可以访问到这个函数作用域的变量
return function () {
console.log(num)
}
}
let o = father();
o();
执行不是把参数函数拉来进来执行,而是在当前所在的位置调用执行。
function fun(a) {
let num = 123;
a()
}
fun(function () { console.log(num) })
let fn = (a, b) => {
return a + b;
}
let re = fn(1, 2);
let [ a, b, [, c, d]] = ['张飞', '赵云', '关羽', '张辽', ['林冲', '鲁智深', '武松', '宋老板']]
// 把属性名当做变量名即可
let { uname:userName,dog:{uname} } = {
uname : '张三丰',
dog : {
uname : '小狗子',
age : 1,
},
age : 22,
sex : '男',
score : 99,
index : 6,
}
console.log(userName, uname)//张三丰 小狗子
//创建
let obj = {
// 属性名:属性值,
// 键值对
// 成员
uname: '张三丰',
age: 22,
sex: '男',
taiji: function () {
console.log('打太极');
},
}
//遍历
for (let k in obj) {
console.log( arr[k] );
}
function Person (uname, age, sex) {
// 设置属性
this.uname = uname;
this.age = age;
this.sex = sex;
this.eat = function () {
console.log('吃饭');
};
}
// 实例化对象,返回的是一个对象,未赋值里面也有这个属性
let o = new Person('张三丰', 22, '男');
console.log( o.uname );
function A() { }
function B() { }
let obj = new B();
// instanceof:用于判断一个对象是否是另外一个构造函数的实力对象
// 对象 instanceof 构造函数
console.log( obj instanceof B );//true
// constructor:指回构造函数本身
console.log( obj.constructor );//ƒ B() { }
let obj = new Object( {uname : '阿飞', age : 22, sex : '男'} );
// 获取对象的索引值,返回的是一个数组
let re = Object.values(obj);
//任何一个数组都是Array构造函数的实例化对象
let ary = new Array(1, 2, 3);
// 字面量:
let reg = /abc/;
// 构造函数:
let reg1 = new RegExp(/abc/);
常用的几个数组方法总结如下:
//concat:用于拼接为新数组,注意返回的是一个新数组
let arr = [1, 2, 3];
let ary1 = ['a', 'b'];
let reArr = arr.concat(ary1, '张飞', '关羽');
console.log(reArr);//[1, 2, 3, 'a', 'b', '张飞', '关羽']
console.log(arr)//[1, 2, 3]
//join():用于连接数组的每个元素成为字符串
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
let str = arr.join('-');//空字符串代表直接相连
console.log(str);//a-b-c-d-e-f-g-h
//reverse:翻转数组顺序
let arr = [1, 2, 3];
let re = arr.reverse();
console.log(re);//[3, 2, 1]
//indexOf:查找某个元素在数组中首次出现的索引位置(从01开始),找不到就是返回-1
let arr = ['a', 'b', 'c', 'd', 'a', 'b', 'f'];
let re = arr.indexOf('m');
console.log(re);//-1
//lastIndexOf:查找某个元素在数组中尾次出现的索引位置,找不到就返回-1
let re = arr.lastIndexOf('b');
console.log(re)//5
// 正序排列(里面的函数固定写法,不写的话就按照编码的值逐位比较大小了):
let re = arr.sort(function (a, b) { return a - b; });
// 倒序排列
let re = arr.sort(function (a, b) {return b - a;});
//Array.from(伪数组名)伪数组转真数组
let lis = document.querySelectorAll('li');
let arr = Array.from(lis);
**//forEach:用于遍历数组(3个参数可以省略)**
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
arr.forEach(function (item, index, o) {
// 第一个参数:代表数组的每一项(每个元素)
// 第二个参数:代表数组的每一项的索引值(索引值)
// 第三个参数:代表当前数组本身(单独输出会输出数组长度个,因为要遍历完)
console.log(item, index, o);
});
**//forEach常用写法:后面的几个方法都有遍历的功能**
arr.forEach(item => {
console.log(`姓名:${item.uname},年龄${item.age},性别${item.sex}`);
});
// find:用于查找首次出现的满足条件的值,并返回,没有返回undefined
let re = [2, 6, 4, 7, 9, 3].find( function (item, index, o) {
return item > 5;
} )
console.log(re);//6
// findIndex:用于查找首次出现的满足条件的值,并返回期所在索引值,没有返回-1
let re = [2, 6, 4, 7, 9, 3].findIndex( function ( item, index, o ) {
return item > 5;
} );
console.log(re);//1
// some:用于查找如果有一个满足条件返回true
let re = [2, 6, 4, 7, 9, 3].some( function (item, index, o) {
return item > 5;
} )
console.log(re);//true
// every:用于查找满足条件的元素,如果都满足返回true,否则就是false
let re = [2, 6, 4, 7, 9, 3].every( function (item, index, o) {
return item > 5;
} );
console.log(re);//false
// filter:筛选数组把满足条件的元素放到新数组返回
let re = [2, 6, 4, 7, 9, 3].filter( function (item, index, o) {
return item > 5;
} );
console.log(re);// [6, 7, 9]
// map:遍历数组让每个元素执行一边回调函数,把所有结果放到新数组返回
let re = [2, 6, 4, 7, 9, 3].map(function (item, index, o) {
return item * item;
});
console.log(re);//[4, 36, 16, 49, 81, 9]
在 JavaScript 中的字符串、数值、布尔这三个简单数据类型具有对象的使用特征,如具有属性和方法,之所以具有对象特征的原因是字符串、数值、布尔类型数据是 JavaScript 底层使用 Object 构造函数“包装”来的,被称为包装类型。
字符串常用属性见如下参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String
常用的字符串方法如下:
let str = 'abcdefgabcd';
//属性:length(获取长度)
console.log( str.length );//11
console.log( str[1] );
for (let i = 0; i < str.length; i++) {
console.log( str[i] );
}
//trim:用于去除字符串两端(注意只是两端的)空白
let str = ' abc defgabcd ';
console.log(str);
console.log(str.trim());//abc defgabcd
let str = 'abcdefgabcd';
// split:分割字符串,如果里面是空字符串,则依次分割
let re = str.split('c');// ['ab', 'defgab', 'd']
console.log(re);
let str = 'abcdeFGabcd';
// toLowerCase:把字母转成小写
// let re = str.toLowerCase();
// toUpperCase:把字母转成大写
let re = str.toUpperCase();
console.log(re);//ABCDEFGABCD
let str = 'abcdefgabcd';
// indexOf:查找某个元素首次出现的索引值,找不到就是-1
// let re = str.indexOf('mm');//-1
// lastIndexOf:查找某个元素尾次出现的索引值,找不到就是-1
let re = str.lastIndexOf('cd')
console.log(re);//9
//字符串截取,索引从0开始:
//注意:如果只有一个参数,那么从这个索引值位置开始一直截取到最后
let str = 'abcdefgabcd';
//slice:截取字符串
//字符串.slice(start,end);从start索引值位置截取字符串截取到end索引位置
//注意:不包含end
let re = str.slice(1, 4);//bcd
//substring:截取字符串
//字符串.substring(start,end)从start索引值位置截取字符串截取到end索引位置
//注意:end索引位置上的字符取不到,相比于slice,可以自动识别大小值
let re = str.substring(4, 1);//bcd
//substr:截取字符串
//字符串.substr(start, length)从start索引位置开始截取字符串,截取length个
let re = str.substr(1, 4);
console.log(re)//bcde
let num = 66;
console.log(num instanceof Number);//false
let num = new Number(67);
console.log(num instanceof Number);//true
//方法 :
//toFixed(number):用于保留几位有效数字(会进行四舍五入)
let price = 66.36875123;
price = price.toFixed(3);
console.log(price);//66.369
//字面量构造
let flag = true;
//对象构造
let flag = new Boolean(true);
console.log(flag);
// 公共属性的构造函数
function Person () {
this.head = 1;
this.eyes = 2;
this.legs = 2;
this.say = function () {console.log('say');}
this.eat = function () {console.log('eat');}
}
//新的构造函数
function Chinese () {
this.language = '汉语';
this.skin = 'yellow';
}
// 1、把对象赋值给原型对象
Chinese.prototype = new Person();
// 2、指回构造函数本身
Chinese.prototype.constructor = Chinese;
// 实例对象
let c1 = new Chinese();
console.log(c1);//c1就可以访问到公共和自己的所有成员
//1、普通函数:无明显是window,有是调用者
function fn () {
console.log(this);//window
}
fn();
function fn() {
console.log(this);//document
}
document.addEventListener('click', fn);
//2、构造函数:实例化对象
function Perosn (uname, age) {
this.uname = uname;
this.age = age;
console.log(this);
}
let obj1 = new Perosn('阿飞', 22);
console.log(obj1);//指向obj1
let obj2 = new Perosn('李寻欢', 23);
console.log(obj2);//指向obj2
//3、对象调用方法:调用者
let obj = {
uname: '张三丰',
age: 22,
fei: function () {
console.log(this);//指向obj
}
}
obj.fei();
//4、事件处理函数:事件源如下是document,或者是标签对象等
document.addEventListener('click', function () {
console.log(this);//document
});
// 5. 定时器函数,立即指向函数(自调用函数)指向window,可省略
window.setInterval(function () {
console.log(this);//window
}, 1000)
;(function () {
console.log(this);//
})()
//6.箭头函数认为不存在this,箭头函数中的this指向的是上级作用域的this,尽量少用
document.addEventListener('click', function () {
window.setInterval(() => {
console.log(this);//document
}, 1000)
});
// 函数.call(this,arg1, arg2,......)
// 函数调用call、call会调用函数执行,在执行的过程中,改变this的指向
function fun (a, b) {
console.log(this, a, b)//obj,1,2//初始情况下是指向window的
}
let obj = {uname : '张三丰', age : 22};
fun.call(obj, 1, 2);
//再次调用fun(),还是会指向window,直再执行call的时候会改变
//apply:函数.apply(this, [arg1, arg2,......]),数组里面的会对应进行一一对应传参,其它和all一摸一样
function fn (a, b) {
console.log(this, a, b);//obj 111 222
}
let obj = {uname : '阿飞'};
fn.apply(obj, [111, 222]);
//常用的场景,如求解数组里的最大值
//方法一:
let arr = [23, 66, 33, 19, 4, 7];
let re = Math.max.apply(null, arr);
console.log( re );//66
//方法二:... rest参数:剩余参数,函数,解构赋值
//... 扩展运算符:数组,字符串,对象
let arr = [23, 66, 33, 19, 4, 7];
// ...扩展运算符
console.log(...arr)//23 66 33 19 4 7
let re = Math.max(...arr);
console.log(re);//66
// bind:函数.bind(this, arg1, arg2,......);
function fn (a, b) {
console.log(this, a, b);
}
let obj = {uname : '李寻欢', age : 22};
//fn.bind(obj)//无输出
//fn.bind(obj, 123, 456)();//obj 123 456
//fn.bind(obj)(123, 456);//obj 123 456
class Person {
// 静态属性
static language = '汉语';
static skin = 'yellow';
//静态方法,注意不要加function
static eat () {
console.log('吃');
}
// 实例成员
uname = '张三丰';
age = 23;
sex = '男';
hi () {
console.log('hi');
}
}
//实例化,调用类似,静态只能类名(构造函数)调用,实例只能实例对象调用
let obj = new Person();
console.log( obj.uname );
obj.say();
class Person {
constructor (uname, age) {
this.uname = uname;//不要漏掉this
this.age = age;
}
say () {
console.log('说话');
}
}
let obj = new Person('张三丰', 22);
console.log(obj);
let obj1 = new Person('阿飞', 23);
console.log(obj1);
extends:申明一个类为子类, super:调用父类的方法
class Father {
constructor (uname, age) {
this.uname = uname;
this.age = age;
}
qian () {
console.log('赚他一个亿');
}
}
// 继承(记得先写父,再写子):
// super:调用父类的方法
//如果相同,优先调用自己的
class Son extends Father {
constructor (uname, age, score) {
// 先调用super,再设定自己的成员
super(uname, age);
this.score = score;
}
qian () {
// 方法就近原则,
// 如果依旧想要调用父类里面的方法,用super
super.qian();
console.log('2mq');
}}
let obj = new Son('儿子', 2,99);
console.log( obj );//里面也有了father里面的属性
obj.qian();//赚他一个亿 2mq
Object.assign(newObj, obj);
//等价于下述代码
// for ( let key in obj ) {
// newObj[key] = obj[key]
// }
全部拷贝,如果是复杂的数据类型,在进行遍历,直到全部是简单数据类型的赋值为止,运用递归的思想,代码固定,如下:
// 遍历
// 如果遇到obj[key]是复杂类型,再遍历操作
function kaobei (newObj, obj) {
for ( let key in obj ) {
if ( obj[key] instanceof Array ) {// obj[key] 是数组,不要误用typeof,因为复杂数据类型的typeof都是object
//上面那行代码也可以改写为if (obj[key].constructor == Array)
// 保证newObj[key]是数组
newObj[key] = [];
kaobei(newObj[key], obj[key]);
} else if ( obj[key] instanceof Object ) {// obj[key] 是对象
// 保证newObj[key]是对象
newObj[key] = {};
kaobei(newObj[key], obj[key])
} else {
newObj[key] = obj[key];
}
}
}
kaobei(newObj, obj);