一个公司做两个网站的好处,网站建设征集通讯员的通知,搜索引擎营销是什么,wordpress 增加 专题来讲一讲原型链 原型链只存在于函数之中
四个规则
1、引用类型#xff0c;都具有对象特性#xff0c;即可自由扩展属性。
2、引用类型#xff0c;都有一个隐式原型 __proto__ 属性#xff0c;属性值是一个普通的对象。
3、引用类型#xff0c;隐式原型 __proto__ 的属… 来讲一讲原型链 原型链只存在于函数之中
四个规则
1、引用类型都具有对象特性即可自由扩展属性。
2、引用类型都有一个隐式原型 __proto__ 属性属性值是一个普通的对象。
3、引用类型隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值。
4、当你试图得到一个对象的某个属性时如果这个对象本身没有这个属性那么它会去它的隐式原型 __proto__也就是它的构造函数的显式原型 prototype中寻找。 四个知识点
Object 是所有对象的爸爸所有对象都可以通过 __proto__ 找到它Function 是所有函数的爸爸所有函数都可以通过 __proto__ 找到它函数的 prototype 是一个对象对象的 __proto__ 属性指向原型 __proto__ 将对象和原型连接起来组成了原型链 const obj {};
const arr [];
const fn function() {}obj.__proto__ Object.prototype // true
arr.__proto__ Array.prototype // true
fn.__proto__ Function.prototype // truenew 做了什么 var obj new F();
// 做了什么
var obj {};
obj.__proto__ F.prototype;
F.call(obj);
第一行我们创建了一个空对象obj;
第二行我们将这个空对象的__proto__成员指向了F函数对象prototype成员对象;
第三行我们将F函数对象的this指针替换成obj然后再调用F函数.
我们可以这么理解: 以 new 操作符调用构造函数的时候函数内部实际上发生以下变化
1、创建一个空对象并且 this 变量引用该对象同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用并且最后隐式的返回 this. prototype和__proto__
1. __proto__是每个对象都有的一个属性而prototype是函数才会有的属性。
2. __proto__指向的是当前对象的原型对象而prototype指向的是以当前函数作为构造函数构造出来的对象的原型对象。你的__proto__来自你构造函数的prototype;所有对象字面量都是通过Object()构造出来的换言之对象字面量__proto__ 属性都指向Object.prototype
prototype: 显式原型
每一个函数在创建之后都会拥有一个名为prototype的属性这个属性指向函数的原型对象。
通过Function.prototype.bind方法构造出来的函数是个例外它没有prototype属性 JavaScript中任意对象都有一个内置属性[[prototype]]在ES5之前没有标准的方法访问这个内置属性但是大多数浏览器都支持通过__proto__来访问。ES5中有了对于这个内置属性标准的Get方法Object.getPrototypeOf().
Object.prototype 这个对象是个例外它的__proto__值为null 隐式原型指向创建这个对象的函数(constructor)的prototype
作用是什么:显式原型的作用用来实现基于原型的继承与属性的共享。 __ proto__: 隐式原型
隐式原型的作用构成原型链同样用于实现基于原型的继承。举个例子当我们访问obj这个对象中的x属性时如果在obj中找不到那么就会沿着__proto__依次查找。
__proto__的指向:__proto__的指向到底如何判断呢根据ECMA定义 to the value of its constructor’s prototype ----指向创建这个对象的函数的显式原型。所以关键的点在于找到创建这个对象的构造函数接下来就来看一下JS中对象被创建的方式一眼看过去似乎有三种方式1对象字面量的方式 2new 的方式 3ES5中的Object.create() 但是我认为本质上只有一种方式也就是通过new来创建。为什么这么说呢首先字面量的方式是一种为了开发人员更方便创建对象的一个语法糖本质就是 var o new Object(); o.xx xx;o.yyyy; 再来看看Object.create(),这是ES5中新增的方法在这之前这被称为原型式继承 构造函数的prototype和其实例的__proto__是指向同一个地方的这个地方就叫做原型对象
Function和Object 构造函数的prototype和其实例的__proto__是指向同一个地方的咱们可以来验证一下
函数是Function构造函数的实例对象是Object构造函数的实例
那Function构造函数和Object构造函数他们两个又是谁的实例呢
function Object()其实也是个函数所以他是Function构造函数的实例function Function()其实也是个函数所以他也是Function构造函数的实例没错他是他自己本身的实例 console.log(Function.prototype Object.__proto__) // true
console.log(Function.prototype Function.__proto__) // true
constructor和prototype是成对的你指向我我指向你
function fn() {}console.log(fn.prototype) // {constructor: fn}
console.log(fn.prototype.constructor fn) // true原型链
什么是原型链呢其实俗话说就是__proto__的路径就叫原型链 原型继承 说到原型就不得不说补充一下原型继承这个知识点了原型继承就是实例可以使用构造函数上的prototype中的方法 instanceof 作用判断B的prototype是否在A的原型链上 A instanceof B 【JS】图解原型链相关练习题带你彻底搞懂原型链这可能是掘金画原型链画的最正的 - 掘金
第一题
主要坑是 f的构造函数是 F F的构造函数是Obj
f的所有方法从以下找
f.__proto__ F.protyotype F.__proto__ obj.protyotype obj.proto null
F的所有方法从以下找
F.__proto__ Function.protyotype Function.__proto__ obj.protyotype obj.proto null
var F function() {};Object.prototype.a function() {console.log(a);
};Function.prototype.b function() {console.log(b);
}var f new F();f.a();
f.b();F.a();
F.b();第二题
b的所有方法从以下找
b.__proto__ A.protyotype A.proto obj.protyotype obj.proto null
c的所有方法从以下找
b.__proto__ A.protyotype A.proto obj.protyotype obj.proto null
本体核心是每次new时使用的都是构造函数最新的prototype 老的构造函数引用老的prototype 并不会被覆盖
var A function() {};
A.prototype.n 1;
var b new A();
A.prototype {n: 2,m: 3
}
var c new A();console.log(b.n);
console.log(b.m);console.log(c.n);
console.log(c.m);第三题
函数的构造函数一定是Function 对象的构造函数 可能是obj 也可能是new Function
var foo {},F function(){};
Object.prototype.a value a;
Function.prototype.b value b;console.log(foo.a);
console.log(foo.b);console.log(F.a);
console.log(F.b);第四题
new 的时候会函数内this会重新赋值进行覆盖
function A() {}
function B(a) {this.a a;
}
function C(a) {if (a) {this.a a;}
}
A.prototype.a 1;
B.prototype.a 1;
C.prototype.a 1;console.log(new A().a);
console.log(new B().a);
console.log(new C(2).a);