js 面向对象
类和对象
与 java 大致相同
class Star {
constructor(uname) {
this.uname = uname;
}
sing(song) {
console.log(this.uname + '在唱' + song);
}
}
var ldh = new Star('刘德华');
ldh.sing('冰雨');
类的继承
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
}
}
var son = new Son(12, 13);
继承中的属性或方法查找的就近原则
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
say() {
console.log(super.say() + '的儿子');
}
}
var son = new Son();
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
add() {
console.log(this.x + this.y);
}
}
class Son extends Father {
constructor(x, y) {
super(x, y);
this.x = x;
this.y = y;
}
sub() {
console.log(this.x - this.y);
}
}
var son = new Son(3, 4);
son.add();
son.sub();
注意点:
- 在ES6中没有变量提升,所以必须先定义类,才能通过类实例化对象。
- 类里面的共有属性和方法一定要加this使用。
- 类里面的this指向问题。
- constructor 里面的this指向实例对象,方法里面的this指向这个方法的调用者。
var that;
class Star {
constructor(uname, age) {
that = this;
this.uname = uname;
this.age = age;
this.btn = document.querySelector('button');
this.btn.onclick = this.sing;
}
sing() {
console.log(that.uname + '在唱歌');
}
}
var ldh = new Star('刘德华', 18);
构造函数和原型
构造函数的方式
function Star(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sing = function(song) {
console.log(song);
}
}
var obj = new Star('刘德华', 60, '男');
obj.sing('冰雨');
console.log(obj.age);
Star.height = 170;
console.log(Star.height);
console.log(obj.height);
原型对象
构造函数的问题:相同的方法会开辟不同的内存空间,导致浪费
解决:通过原型对象来共用函数
function Star(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
var ldh = new Star('刘德华', 60, '男');
var zxy = new Star('张学友', 62, '男');
Star.prototype.sing = function() {
console.log(this.name + '唱歌');
}
console.log(ldh.sing == zxy.sing);
ldh.sing();
zxy.sing();
对象原型
console.log(ldh.__proto__);
原型constructor 函数
Star.prototype = {
constructor: Star,
sing: function() {
console.log(this.name + '在唱歌');
},
dance: function() {
console.log(this.name + '在跳舞');
}
}
console.log(Star.prototype.constructor);
console.log(ldh.__proto__.constructor);
原型链
console.log(Star.prototype.__proto__ == Object.prototype);
console.log(Object.prototype.__proto__);
对象成员查找规则
function Star(name, age) {
this.name = name;
this.age = age;
}
var ldh = new Star('刘德华', 60);
var zxy = new Star('张学友', 62);
Object.prototype.sex = '男';
ldh.sex = '女';
console.log(ldh.sex);
console.log(ldh.toString());
扩展内置对象
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
var arr = [3, 5, 7];
console.log(arr.sum());
call 方法
function fn(x, y) {
console.log(this.name);
console.log(x + y);
}
var o = {
name: 'andy'
}
fn.call(o, 1, 2);
通过call方法实现继承
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
function Son(uname, age, score) {
Father.call(this, uname, age);
this.score = score;
}
var son = new Son('李四', 18, 91);
console.log(son);
继承,添加方法相关
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log(100000);
};
function Son(uname, age, score) {
Father.call(this, uname, age);
this.score = score;
}
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.exam = function() {
console.log('孩子要考试');
}
var son = new Son('刘德华', 18, 100);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
ES5新增方法
数字方法
forEach() map() filter() some() every()
forEach()
var arr = [3, 4, 5];
var sum = 0;
arr.forEach(function(value, index, array) {
console.log(value);
console.log(index);
console.log(array);
sum += value;
})
console.log(sum);
filter() 返回符合条件的新数组
var arr = [3, 4, 5];
var arr2 = arr.filter(function(value, index, array) {
return index > 1;
})
console.log(arr2);
some()
var arr = [3, 4, 5, 6];
var flag = arr.some(function(value, index, arr) {
return value > 4;
})
console.log(flag);
foreach 与 some 的区别
some 找到后就会停止循环 return true 的时候停止
foreach 会一直寻找
字符串方法
str.trim() 去除两边的空格
var str = ' andy ';
console.log(str);
console.log(str.trim());
Object.keys(obj) 获取所有的键,并返回成一个数组
var obj = {
id: 1,
pname: '小米',
price: 1999,
num: 2000
}
var arr = Object.keys(obj);
console.log(arr);
arr.forEach(function(value) {
console.log(value);
})
Object.defineProperty(obj, prop, descriptor) 不能覆盖原有写上的
descriptor 的说明, 其以对象形式书写
- value:设置属性的值,默认为undefined
- writable:值是否可以重写。true | false 默认为false
- enumerable:目标属性是否可以被枚举。true | false 默认为false
- configurable:目标属性是否可以被删除或是否可以再次修改特性 true | false 默认为false
var obj = {
id: 1,
pname: '小米',
price: 1999,
num: 2000
};
Object.defineProperty(obj, 'id', {});
obj.id = 2;
console.log(obj.id);
Object.defineProperty(obj, 'address', {
value: '中国山东蓝翔技校',
enumerable: false
});
console.log(Object.keys(obj));
Object.defineProperty(obj, 'address', {
value: '中国山东蓝翔技校',
enumerable: false,
configurable: false
});
console.log(obj);
console.log(Object.keys(obj));
函数
var f = new Function('a', 'b', 'console.log(a + b)');
f(1, 2);
几种调用方法 与this指向
function fn() {
console.log(this);
}
fn();
var o = {
say: function() {
console.log(this);
}
}
o.say();
function Star(name) {
this.name = name;
console.log(this);
}
var ldh = new Star('lisi');
btn.onclick = function() {
console.log(1);
}
setInterval(function() {
console.log(1);
}, 1000);
(function(name){
console.log(1);
})(name)
改变this指向
call() 方法同上笔记 主要用来实现继承
apply() 方法 参数一为调用对象,参数二为数组
var arr = [3, 5, 12, 34, 9];
var max = Math.max.apply(Math, arr);
console.log(max);
bind(thisArg, arg1, arg2, …) 不会调用函数,改变this指向 返回改变了指向的函数拷贝
function fn(x, y) {
console.log(this);
console.log(x + y);
}
var o = {
name: 'andy'
};
var f = fn.bind(o, 1, 2);
f();
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
this.disabled = true;
setTimeout(function() {
this.disabled = false;
}.bind(this), 2000);
}
}
严格模式
<script>
'use strict'
</script>
<script>
(function () {
'use strict'
})()
</script>
<script>
function fn() {
'use strict'
}
function fn2() {
}
</script>
变量规定:变量先声明,再使用 不能使用delete删除
this指向
- 全局作用域this变为undefined,原先是window
- 由于第一条,构造函数不加new用不了
函数变化
- 不能有重名的参数
- 函数必须声明在顶层,如 if, for 中不能再套函数
高阶函数
它接收函数作为参数或者将函数作为返回值输出
function fn(a, b, callback) {
console.log(a + b);
callback && callback();
}
fn(2, 3, function() {
console.log('事后抽烟');
})
闭包
闭包(closure) 指有权访问另一个函数作用域中的变量的函数
延伸了变量的作用范围。
function fn() {
var num = 10;
return function() {
console.log(num);
}
}
var f = fn();
f();
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i)
}
浅拷贝
Object.assign(目标,原对象)
深拷贝
正则表达式
var regexp = new RegExp(/表达式/);
var regexp = /表达式/;
var regexp = /abc/;
console.log(regexp.test('adsabcdasf'));
var regexp = /^abc/;
var regexp = /abc$/;
var regexp = /^abc$/;
var regexp = /[abc]/;
var regexp = /^[abc]$/;
var regexp = /[a-z]/;
var regexp = /[^a-z]/;
var regexp = /^a+$/;
var regexp = /^a*$/;
var regexp = /^a?$/;
var regexp = /^3{3}$/;
var regexp = /^3{3,}$/;
var regexp = /^3{3,12}$/;
var regexp = /^(abc){3}$/;
预定义类
预定义类 | 说明 |
---|
\d | 相当于[0-9] | \D | 零到九以外的数字 | \w | 任意字母数字下划线[A-Za-z0-9] | \W | 上述以外的 | \s | 匹配空格(包括换行符、制表符、空格符)[\t\r\n\v\f] | \S | 上述以外的 |
字符替换
var ta = document.querySelector('textarea');
ta.onblur = function() {
var result = ta.value.replace(/gay|离谱/g, '**');
ta.value = result;
}
ES6
let 声明块级作用域变量
不存在变量提升
console.log(a);
let a = 1;
暂时性死区
var num = 1;
if (true) {
console.log(num);
let num = 2;
}
const 变量 不可变
解构赋值
let [a, b, c] = [1, 2, 3];
let {name, age} = {name: '张三', age: 20};
console.log(name);
console.log(age);
let {name: myname, age: myage} = {name: '张三', age: 20};
console.log(myname);
console.log(myage);
箭头函数
const fn = () => {
console.log(1);
}
fn();
const sum = (num1, num2) => num1 + num2;
console.log(sum(1, 2));
const print = e => console.log(e);
print(1);
const obj = {name: '张三'};
function fn() {
console.log(this);
return () => {
console.log(this);
}
}
const resFn = fn.call(obj);
resFn();
var obj = {
age: 20,
say: () => {
console.log(this);
}
}
obj.say();
剩余参数
const sum = (first, sceond, ...args) => {
let total = 0;
args.forEach(e => total += e);
return total;
}
console.log(sum(10, 20, 40));
const sum = (first, ...args) => {
let total = 0;
args.forEach(e => total += e);
return total;
}
console.log(sum(10, 20, 40));
let arr = ['jase', 'didi', 'pici'];
let [s1, ...s2] = arr;
console.log(s1);
console.log(s2);
扩展运算符
let arr = [1, 2, 3];
console.log(...arr);
let arr1 = [1, 2, 4];
let arr2 = [2, 5, 8];
let arr3 = [...arr1, ...arr2];
console.log(arr3);
arr1.push(...arr2);
console.log(arr1);
let divs = document.querySelectorAll('div');
console.log(divs);
let arr = [...divs];
console.log(typeof(arr));
console.log(arr);
Array的扩展方法
from();
let arrLike = {
'0': 'lis2',
'1': 'lis2',
'2': 'lis3',
'length': 3
}
console.log(arrLike);
let res = Array.from(arrLike);
console.log(res);
let arrLike = {
'0': '2',
'1': '3',
'2': '4',
'length': 3
}
let res2 = Array.from(arrLike, item => item * 2);
console.log(res2);
find();
let ary = [{
id: 1,
name: 'lisi'
}, {
id: 2,
name: 'whwu'
}]
let res = ary.find(item => item.id == 2);
console.log(res);
findIndex();
let arr = [1, 3, 4, 11];
let res = arr.findIndex(item => item > 3 );
console.log(res);
includes();
let arr = [1, 3, 4, 11];
let res = arr.includes(3);
console.log(res);
String 扩展方法
模板字符串
let who = {
name: 'zhangsan',
age: 18,
sex: '男'
};
let name = `
<div>${who.name}</div>
<div>${who.age}</div>
<div>${who.sex}</div>
`;
console.log(name);
function fn() {
return '桑桑';
}
let str = `this is ${fn()}`;
console.log(str);
let str = 'hello jack 1098';
console.log(str.startsWith('hello'));
console.log(str.endsWith('1098'));
console.log('s'.repeat(5));
let set = new Set([1, 1, 2, 3]);
console.log(set);
let arr = [...set];
console.log(arr);
set.add() set.delete() set.has() set.clear()
const set = new Set([1, 1, 2, 3]);
set.forEach(e => console.log(e))
|