<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="div1"></div>
<script>
console.dir(div1);
//div , a , doucument ,window
//自己去看方法总结
function Fn() {
this.x = 100;
this.y = 200;
//在类的函数体中写的this.xxx=xxx都是给当前类的实例,增加的私有的属性或方法
}
Fn.prototype.getX = function () {
console.log(this.x);
//在类的原型上写的,都是给当前类的实例或者当前的类,增加的公有的属性或方法
};
Fn.prototype.getY = function () {
console.log(this.y);
};
var f1 = new Fn;
//检测某一个函数是否是一个类的实例 用instanceof
var f2 = new Fn;
//1.所有的函数数据类型(普通函数、类)都天生自带一个属性:prototype,它存储的值是一个对象数据类型的值,浏览器会默认为其开辟一个堆内存
//2. 在浏览器给prototype默认开辟的这个堆内存上有个一个默认的属性constructor 指向当前类本身
//3. 每个对象数据类型(普通的对象、数组、正则、实例、prototype)都天生自带一个属性__proto__,指向当前实例所属类的原型
//2.关于原型链的this问题
function Fn() {
this.x = 100;
this.getX = function () {
console.log(this.x);
}
}
Fn.prototype.getX = function () {
console.log(this.x);
};
var f1 = new Fn;
f1.getX();
f1.__proto__.getX();
var f2 = new Fn;
//1、看方法执行的时候,"."前面是谁,this就是谁
//2、把函数体重的this替换成分析的结果
//3、按照原型链的查找模式找到对应的值即可
//
function Fn() {
this.x = 100;
this.getX = function () {
console.log(this.x);
}
}
Fn.prototype.getX = function () {
console.log(this.x);
};
Fn.prototype.setX = function (n) {
this.x = n
};
var f1 = new Fn;
f1.getX();//this ->f1,console.log(f1.x)->100
f1.__proto__.getX();//this->f1.__proto__,console.log(f1.__proto__.x)->undefined (略过私有的到了公有的 公有的上没有x 所以为undefined)
Fn.prototype.setX(300);//this->Fn.prototype,Fn.prototype.x = 300
f1.getX();// 100
f1.__proto__.getX();// 300
f1.setX(500);//this ->f1 ->f1.x = 500;把私有的修改为500
f1.y = 300;//给f1自己本身增加了一个私有y属性,属性值为300,与f1无关
f1.__proto__.y = 1000;//在原型上增加了一个y属性,y的属性值为1000;与f2有关了,因为是原型上的
//3、在内置类的原型上扩展方法
var ary = [12,23,34];
//要模拟pop
Array.prototype.pop = function () {
//this ->ary
this.length--;
};
ary.pop();//this ->ary
console.log(ary);
ary.__proto__.pop();//this -> ary.__proto__ -> Array.prototype
console.log(ary);
//基于数组原型添加一个数字去重的方法
//基于内置类的原型扩展方法,我们需要注意的事项,我们自己编写的方法名最好加上特殊前缀,放置把内置的方法覆盖掉
Array.prototype.myUnique = function unique () {
//this ->ary 当前操作的那个数组
var obj = {};
for(var i = 0; i <this.length;i++){
var cur = this[i];
if (obj[cur]==cur) {
this[i] = this[this.length-1];
this.length--;
i--;
continue;
}
obj[cur] = cur;
}
obj = null;
return this;//实现链式写法的办法
};
ary.unique();
ary.sort(function (a,b) {
return a - b;//从小到大
}).reverse().slice(0,5).pop();//链式写法
//链式写法核心原理:不仅得到了想要的结果,而且返回值还需要时当前这个类的实例,只有这样才能一直链下去
//reverse()翻转排序
console.log(ary);
ary.myUnique().sort(function (a,b) {
return a -b;
});
//思考题 1.基于number内之类扩展的两个方法plus,minus
// (5).plus(3).minus(2) 5+3-2 = 6
// 2.slice这个方法实现的非常强大,我们自己写一个mySlice实现和slice一模一样的方法(要求数组中现有的方法一个都不能用)
//slice(n,m)
//slice(n) slice(0)
//n和m是负数
//n>m是负数
//n或m超出了整个数组的范围
//批量设置原型的公共方法
function Fn() {
this.x = 100;
}
Fn.prototype.a = function () {
};
Fn.prototype.b = function () {
};
Fn.prototype.c = function () {
};
//第一种办法, 给Fn.prototype起一个小名
var pro = Fn.prototype;
pro.a = function () {
};
pro.b = function () {
};
pro.c = function () {
};
//第二个办法 自己重构
Fn.prototype = {
constructor:Fn,
b:function () {
},
c:function () {
}
};
var f = new Fn;
f.a();//undefined
//1、如果之前原型上存在一些方法的话,我们现在新创建的这个对象会把之前写的那些方法都给覆盖掉,所以浏览器内置类是禁止自己创建一个新对象扩展原型方法的,防止我们Array.prototype={}把内置方法都干没了
//2、自己创建的对象中不会天生自带constructor,所以导致了我们f.constructor 的结果是Object而不是我们认为的Fn了
Array.prototype={};//所有的内置类都不支持直接覆盖
</script>
</body>
</html>
原型链复习参考
最新推荐文章于 2022-06-23 20:41:41 发布