JS基本功系列-原型链相关

admin 2022年5月13日22:05:22评论21 views字数 3788阅读12分37秒阅读模式

原型链

1、沿着__proto__寻找继承关系的链条
2、原型本身也有原型,所有对象都有原型
3、原型链的终点在Object.prototype
4、Object.prototype 里面保存了一个toString方法

看一个例子:

// 重写toString方法
Object.prototype.toString=function(){
//this是什么要看执行的时候谁调用了这个函数。
console.log("I'm " + this.name + " And I'm " + this.age);
}

// 构造函数
function Foo(name,age){
this.name = name;
this.age = age;
}

var fn = new Foo('小明',19);
fn.toString(); // I'm 小明 And I'm 19
console.log(fn.toString === Foo.prototype.__proto__.toString); // true

console.log(fn.__proto__ === Foo.prototype); // true
console.log(Foo.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
JS基本功系列-原型链相关
原型链
1、fn的构造函数是Foo(),所以:
fn.__proto__=== Foo.prototype 为true

2、Foo.prototype是一个普通的对象,它的构造函数是Object,所以:
Foo.prototype.__proto__=== Object.prototype 为true

3、 Object.prototype 也是一个对象,但因为是原型链的终点,里面存储null,所以:
Object.prototype.__proto__ === null 为true

4、原型链:当fn调用toString()时,JS发现fn中没有这个方法,
于是它就去Foo.prototype 中去找,发现还是没有这个方法,
然后就去 Object.prototype中去找,找到了,就调用 Object.prototyp e中的t oString() 方法。

原型扩展

// 1、构造函数字面量
var a = {}// 其实是 var a = new Object() 的语法糖
var a = [] //其实是 var a = new Array() 的语法糖
function Foo(){ } //其实是 var Foo = new Function(...)
// 2、对象字面量的 constructor 指向系统自带的构造函数,
var obj1 = {}
console.log(obj1); // {__proto__: {constructor: ƒ Object()}}
obj1.__proto__ === Object.prototype//true

// 用户自定义实例化对象的 constructor 指向自定义的构造函数
function Obj() {}
var obj2 = new Obj();
console.log(obj2); // {__proto__: {constructor: ƒ Obj()}}
// 3、原型的原型是系统自带的 Object 构造出来的
function Obj() {}
var obj = new Obj();
// Obj.prototype
console.log(obj.__proto__); // {constructor: ƒ Obj(), __proto__: {constructor: ƒ Object()}}
// 4、Object.create(参数为对象 或 null) :创建对象,自定义原型
Object.create(对象,null);

// 4.0 new 过程
(1) 实例化obj2
(2) 调用构造函数Obj的初始化属性和方法
(3) 指定实例对象的原型


// 4.1 自定义原型与系统指定原型
function Obj() {}
Obj.prototype.num = 1;
// 自定义原型对象
var obj1 = Object.create(Obj.prototype);
// 系统指定原型对象
var obj2 = new Obj();
// 两种创建出的对象一模一样
console.log(obj1); // Obj { __proto__: {num: 1, constructor: ƒ Obj()}}
console.log(obj2); // Obj { __proto__: {num: 1, constructor: ƒ Obj()}}


// 4.2 修改原型为自定义的对象
var test = { num: 2 }
var obj3 = Object.create(test);
console.log(obj3); // { __proto__: {num: 2, __proto__: {constructor: ƒ Object()}}}


// 4.3 将其他对象作为原型使用-继承
var obj1 = Object.create(null); // 创建obj1空对象
console.log(obj1); // {} obj1没有原型
obj1.num = 1;
var obj2 = Object.create(obj1);
console.log(obj2); // {__proto__:{num: 1}}
console.log(obj2.num); // 1


// 4.4 不是所有的对象都继承于Object.prototype
var obj1 = Object.create(null); // 创建obj1空对象
console.log(obj1); // {} obj1没有原型
// 5、__proto__只能改变,不能重新造
var obj = Object.create(null);
obj.num = 1;
var obj1 = {
count: 2
}
obj.__proto__ = obj1;
console.log(obj); // {num: 1, __proto__: {…}} - __proto__ 深红色,表示自定义的属性,不是原型
console.log(obj.count); // undefined

toString方法

// Object 原型上的 toString 方法
console.log(Object.prototype.toString.call(1)); // '[object Number]'
console.log(Object.prototype.toString.call('a')); // '[object String]'
console.log(Object.prototype.toString.call(true)); // '[object Boolean]'
console.log(Object.prototype.toString.call([1, 2])); // '[object Array]'
console.log(Object.prototype.toString.call({num:1})); // '[object Object]'

// 对象原型重写 toString()
console.log(Number.prototype.toString.call(1)); // '1'
console.log(String.prototype.toString.call('a')); // 'a'
console.log(Boolean.prototype.toString.call(true)); // 'true'
console.log(Array.prototype.toString.call([1, 2])); // '1,2'
console.log(Object.prototype.toString.call({num:1})); // '[object Object]'

call和apply

//call和apply
function test() {}
test(); // 系统隐式 test.call()

// 作用:改变this指向---借用别人的函数实现自己的功能
// 区别:后面传的参数形式不同
function Car(brand, color) {
this.brand = brand; // newCar.brand = brand;
this.color = color; // newCar.color = color;
this.run = function() {
console.log('running');
}
}

var newCar = {
displacement: '3.0'
};

Car.call(newCar, 'Benz', 'red'); // 将Car的this全部改为newCar
console.log(newCar); // {displacement: "3.0", brand: "Benz", color: "red", run: ƒ}

// 常用
Car.apply(newCar, ['Benz', 'red']);
console.log(newCar); // {displacement: "3.0", brand: "Benz", color: "red", run: ƒ}

// 不影响原有对象
var car = new Car('Benz', 'red');
console.log(car); // Car {brand: "Mazda", color: "color", run: ƒ}


原文始发于微信公众号(迪哥讲事):JS基本功系列-原型链相关

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月13日22:05:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JS基本功系列-原型链相关https://cn-sec.com/archives/1004811.html

发表评论

匿名网友 填写信息