一.原型链条的使用
1.检测当前对象是否还有对象
let obj = {
name:"zs",
age:18,
each:{
a:1,
b:2
}
}
// 检测当前对象是否还有对象
console.log(obj.hasOwnProperty("a"));
2.含义
原型链中就是实例对象和原型对象之间的链接。每个函数都有一个prototype属性,这个prototype属性就是我们的原型对象,我们拿这个函数通过new构造函数创建出来的实例对象
3.如图
这就是原型链条的使用结合图所示 会更容易通俗易懂
4.__proto__的指向
- 当访问一个对象的属性或方法时,首先查找这个对象自身有没有
2. 如果没有就查找它的原型(也就是 proto 指向的prototype 原型对象 )
3. 如果还没有找到就查找原型对象的原型(Object的原型对象)
4. 依次类推一直找到Object为止( null )
5. proto 对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条线路
5.示例
function Star(uname,age){
this.uname=uname;
this.age=age;
}
Star.prototype={
constructor: Star,
sing:function(){
console.log('唱歌');
},
movie:function(){
console.log('演电影');
}
}
var ldh=new Star('刘德华',18);
// Star.prototype.ids = 100;
Object.prototype.ids = 99;
ldh.__proto__.show();
// console.log(ldh.ids);
// console.log(ldh.__proto__.ids);
注意
1.
> Star原型对象里面的 __proto__ 原型指向的是 Object.prototype
> console.log(Star.prototype.__proto__ === Object.prototype)
2.
Object.prototype原型对象里的__proto__原型 指向null
console.log(Object.prototype.__proto__)
console.log(Star.prototype.__proto__.__proto__);
二.原型链条操作数组
1.用push,pops ,shifts ,unshifts操作数组
function Star(uname,age){
this.uname=uname;
this.age=age;
}
var _this;
Star.prototype.sing=function(){
console.log('唱歌');
_this=this;
console.log(this);
}
var ldh=new Star('刘德华',18)
ldh.sing();
_this.sing();
console.log(ldh);
console.log(_this === ldh)
console.log(Function.prototype);
console.log(Object.prototype);
console.log(Array.prototype);
Array.prototype.sum = function(user){
console.log(this);
var num = 0;
for(var i=0;i<=user;i++){
num+=i;
}
return this.push(num);
}
var arr = [];
arr.sum(100);
console.log(arr);
Array.prototype.pushs = function(user){
this[this.length] = user
}
var arr = [11,22,33];
arr.pushs(44);
console.log(arr);
Array.prototype.pops = function(){
this.length = this.length-1;
}
var arr = [11,22,33];
arr.pops();
console.log(arr);
Array.prototype.shifts = function(){
for(var i=0;i<this.length-1;i++){
this[i] = this[i+1];
}
this.length = this.length-1;
}
var arr = [11,22,33];
arr.shifts();
console.log(arr);
Array.prototype.unshifts = function(user){
this.length = this.length+1;
for(var i=this.length-1;i>=0;i--){
this[i] = this[i-1];
}
this[0] = user;
}
var arr = [11,22,33];
arr.unshifts(44);
console.log(arr);
2.call()方法原理
Function.prototype.calls = function(user,...a){
if(!user||user==null||user==undefined){
user = window;
}
let fn = Symbol();
user[fn] = this;
return user[fn](...a);
}
let obj = {
func(a,b){
console.log(this);
console.log(this.age);
console.log(a);
console.log(b);
}
}
let obj1 = {
age:"张三"
}
obj.func.calls(obj1,1,2);
3.bind()方法原理
Function.prototype.myBind = function(context) {
// 如果没有传或传的值为空对象 context指向window
if (typeof context === "undefined" || context === null) {
context = window
}
let fn = mySymbol(context)
context[fn] = this //给context添加一个方法 指向this
// 处理参数 去除第一个参数this 其它传入fn函数
let arg = [...arguments].slice(1) //[...xxx]把类数组变成数组,arguments为啥不是数组自行搜索 slice返回一个新数组
context[fn](arg) //执行fn
delete context[fn] //删除方法
}
4.apply原理
apply原理与bind一致 只是第二个参数是传入的数组
Function.prototype.myApply = function (context, args) {
if (!context || context === null) {
context = window;
}
// 创造唯一的key值 作为我们构造的context内部方法名
let fn = Symbol();
context[fn] = this;
// 执行函数并返回结果
return context[fn](...args);
};
完结---------------------------
-----------------总之原型链条一定要记住这张表