这里写目录标题
类与对象
es6 中类和对象的注意点
<button>click</button>
<script>
var that;
var _that;
class Star {
constructor(uname, age) {
// console.log(this);
that = this;
this.uname = uname;
this.age = age;
this.btn = document.querySelector("button");
this.btn.onclick = this.sing;
}
sing() {
//sing里面的this 指向的btn 这个按钮,因为这个按钮调用这个函数
console.log(this);
//因为btn的uname属性是没有属性的 所以是undefined
// console.log(this.uname);
console.log(that.uname); //ldh
//that存储的是constructor里面的this 即实例化的对象
}
dance() {
//dance 指向调用他的实例对象
_that = this;
console.log(this);
}
}
//必须先有类才能进行实例化,实例化
//共有属性和方法一定要加this (传参无需)
var ldh = new Star("刘德华");
// 实例化以后,传进去的参数,或者使用的方法,需要有一个使用者,即当前实例化对象调用方法,或者传属性到具体对象,如果没有this,这个参数或者方法的调用者,就不知道是谁了(个人理解)
console.log(that === ldh); //true
ldh.dance();
console.log(_that === ldh); //true
</script>
构造函数存在的问题
复杂属性问题
function Star(uname, age) {
this.uname = uname;
this.age = age;
// this.sing = function () {
// console.log("我唱歌");
// };
}
Star.prototype.sing = function () {
console.log("我会唱歌");
};
var ldh = new Star("ldh", 18);
var zxy = new Star("zxy", 19);
console.log(ldh.sing === zxy.sing);
ldh.sing();
zxy.sing();
//2.一般情况下,我们的公共属性定要到构造函数里.公共方法放到原型对象里,节约资源
console.log(ldh.__proto__ === Star.prototype); //true
// proto指向prototype;
原型对象指向问题
<script>
function Star(uname, age) {
this.name = uname;
this.age = age;
}
//很多情况下,我们需要手动利用constructor 这个属性指回原来的构造函数
// Star.prototype.sing = function () {
// console.log("我会唱");
// };
// Star.prototype.movie = function () {
// console.log("我会演电影");
// };
//如果修改了原来的原型对象,给原型对象赋值了一个对象,则需要手动指回原来的构造函数
Star.prototype = {
constructor: star,
sing: function () {
console.log("我会唱");
},
movie: function () {
console.log("我会演电影");
},
};
var ldh = new Star("ldh", 18);
</script>
构造函数 实例 原型对象三者关系
父原型对象方法继承问题
// 父构造函数
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
Father.prototype.money = function () {
console.log(10000000000);
};
// 子构造函数
function Son(uname, age, score) {
Father.call(this, uname, age);
this.score = score;
}
//不对
//Son.prototype = Father.prototype;
//子构造函数独有方法
Son.prototype.exam = function () {
console.log("我要考试");
};
var son = new Son("ldh", 18);
var Father = new Father("baba", 45);
console.log(son);
console.log(Father);
简单地将父类的原型对象赋值给子类原型对象,当对子类原型对象添加独有方法时,由于赋值的方式是将父类原型对象的地址给子类原型对象,这就导致了当对子类原型对象进行修改(添加独有方法),会使得父类实例也带有子类独有方法
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200905104314261.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0lUX2xpdHRsZWZpc2g=,size_16,color_FFFFFF,t_70#pic_center)
解决办法
<script>
// 父构造函数
function Father(uname, age) {
this.uname = uname;
this.age = age;
}
Father.prototype.money = function () {
console.log(10000000000);
};
// 子构造函数
function Son(uname, age, score) {
Father.call(this, uname, age);
this.score = score;
}
Son.prototype = new Father();
//如果利用对象形式改了原型对象,要理由constructor指回原来的构造函数
Son.prototype.constructor = Son;
//子构造函数独有方法
Son.prototype.exam = function () {
console.log("我要考试");
};
var son = new Son("ldh", 18);
var Father = new Father("baba", 45);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
</script>
注意问题
利用创建对象的形式修改了原型对象的话,该函数会指向目标函数的构造函数,别忘了用constructor指回原来的构造函数
数组
数组查询
var arr = [1, 2, 3, 4, 5, 6];
// filter foreach some
arr.filter(function (value) {
if (value === 4) {
console.log("找到了");
return true;
}
console.log(11);
});
如果查询的是数组中的唯一元素.则some的性能最高,true后回中断查询
闭包
用处
用于衍生变量的作用范围
Demo
function fn() {
var num = 10;
return function () {
console.log(num);
};
}
var f = fn();
f();
闭包的作用(不是很理解
<body>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
//1.动态添加属性
//1.动态添加的方式
var lis = document.querySelector(".nav").querySelectorAll("li");
for (var i = 0; i < lis.length; i++) {
lis[i].index = 1;//动态地给lis一个索引号
lis[i].onclick = function () {
console.log(i);
};
}
//2.利用闭包的方式得到当前小li的索引号
for (let i = 0; i < lis.length; i++) {
(function (i) {
//小闭包
// console.log(i);
lis[i].onclick = function () {
console.log(i);
};
})(i);
}
</script>
</body>
const变量
//复杂数据类型内的数值可以更改,但是重新赋值会改变其地址,不可更改
<script>
//const 具有块级作用域
// 使用const关键字常量必须赋初始值;
//声明的常量不可更改
const PI = 3.14;
// PI = 100;
const arr = [100, 200];
//复杂数据类型内的数值可以更改,但是重新赋值会改变其地址,不可更改
arr[0] = 123;
arr = [1, 2];
console.log(arr);
</script>
变量声明的区别
如果使用的值无需变动.使用const的效率要比var更高,因为JS无需实时监测 该变量的变动