Object.prototype 原型和原型链
Object.prototype 原型和原型链
原型
Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,有些属性是隐藏的。换句话说,在对象创建时会存在预定义的属性,其中有一个属性就是原型对象。在函数对象中存在原型对象prototype,在普通对象中没有prototype,但存在__proto__。或者说使用function定义的对象与使用new操作符生成的对象之间有一个重要的区别,这个区别就是function定义的对象有一个prototype属性,使用new生成的对象就没有这个prototype属性,存在__proto__。
var o =new Object();
console.log(o.__proto__);
console.log(o.prototype);//undefined
var fn = function(){}
console.log(fn.prototype);//Object {constructor: function}
var f1 = new fn();
console.log(f1.__proto__);
console.log(f1.__proto__===fn.prototype);//true
原型链
那么__proto__是什么?每个对象都会在其内部初始化一个属性,就是__proto__。
普通对象中的__proto__是什么呢? Object的本质函数对象,是通过new Function()创建,所以Object.__proto__指向Function.prototype。同理,Function也是函数对象,因此Function.__proto__同样指向Function.prototype。 Object.prototype对象也有__proto__属性,但它比较特殊,为null。这个由__proto__串起来的直到Object.prototype.__proto__为null的链就是原型链。
console.log(Object.__proto__ === Function.prototype);//true
console.log(Function.__proto__===Function.prototype);//true
console.log(Object.prototype.__proto__);//null
当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。参考下面的例子:
var Fn = function(){};
Fn.prototype.Hello = function(){
console.log("Hello World");
}
var f1 = new Fn();
f1.Hello();//Hello World
首先var f1=new fn(),f1是Fn的实例,可以得出f1.__proto__=Fn.prototype。当我们调用f1.hello()时,首先f1中没有Hello这个属性,于是,它会到他的__proto__中去找,也就是Fn.prototype,而我们在上面定义了 Fn.prototype.Hello=function(){}; 于是,就找到了对应的方法。
从一个更复杂的例子中看原型链的原理:
var Person = function() {};
Person.prototype.Name = function() {
console.log("person name");
}
Person.prototype.Sex = "male or female";
var Younger = function() {};
Younger.prototype = new Person();
Younger.prototype.Age = function() {
console.log("14-28")
};
Younger.prototype.Sex = "female";
var Ann = new Younger();
Ann.Name(); //person name
console.log(Ann.Age()); //14-28
console.log(Ann.Sex); //female
对上述代码,我们可以进行如下分析:
var Younger = function() {}=>:Younger.__proto__=Person.prototype,
Younger.prototype = new Person()=>:Younger.prototype.__proto__ = Person.prototype,
var Ann = new Younger()===>Ann.__proto__=Younger.prototype,
综上可得:
Ann.__proto__.__proto__ = Person.prototype
Ann本身没有Name()方法,于是从Ann.__proto__(Younger.prototype)中找,仍没有找到于是在向上一层Ann.__proto__.__proto__(Person.prototype)中寻找,最终在Person.prototype中找到对应的方法并调用。
同理,Ann本身并没有Age()方法,但在Ann.__proto__(Younger.prototype)存在。
对于Ann.Sex,在Ann.__proto__(Younger.prototype)中已经能够找到,便不再向上寻找,因此输出是female。
Object.prototype 原型和原型链的更多相关文章
- js原型和原型链,以及__proto__、prototype属性
__proto__和prototype属性: 1.__proto__属性: 在JS里,万物皆对象(函数是对象.原型也是对象...).对象都具有属性__proto__,这个属性会指向该对象的原型. 2. ...
- JavaScript深入之从原型到原型链(本文转载)
JavaScript深入之从原型到原型链(本文转载) https://github.com/mqyqingfeng/Blog.原文地址 构造函数创建对象 我们先使用构造函数创建一个对象: functi ...
- 彻底搞懂js原型与原型链
原生的原型链 function fn(){},fn 为 Function的一个实例,原型链为 null -> Object -> Function -> fn: fn.__proto ...
- JavaScript深入之从原型到原型链
构造函数创建对象 我们先使用构造函数创建一个对象: function Person(){} var person = new Person(); person.name = 'Kevin'; cons ...
- JavaScript深入系列(一)--原型和原型链详解
构造函数创建对象 首先我们先使用构造函数创建一个对象: function Person(){} var person = new Person(); person.name = 'tom'; cons ...
- JavaScript 深入之从原型到原型链
1 .构造函数创建对象 我们先使用构造函数创建一个对象: function Person(){ } var p = new Person(); p.name = 'ccy'; console.log( ...
- (转)JavaScript深入之从原型到原型链
构造函数创建对象 我们先使用构造函数创建一个对象: function Person() { } var person = new Person(); person.name = 'Kevin'; co ...
- JS基础-该如何理解原型、原型链?
JS的原型.原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对 ...
- JavaScript深入之从原型到原型链(转载)
构造函数创建对象 我们先使用构造函数创建一个对象: function Person() { } var person = new Person(); person.name = 'Kevin'; co ...
- 原型,原型链,给予原型和class的继承
学习react的时候遇到了class方式的继承语法,原理和代码的解释很详细,值得一读. 原型每个函数(构造函数)都有一个 prototype 属性,指向该函数(构造函数)的原型对象.实例没有 prot ...
随机推荐
- Codeforces Round #311 (Div. 2)C. Arthur and Table
C. Arthur and Table time limit per test 1 second memory limit per test 256 megabytes input standard ...
- bzoj3550: [ONTAK2010]Vacation&&bzoj3112: [Zjoi2013]防守战线
学了下单纯形法解线性规划 看起来好像并不是特别难,第二个code有注释.我还有...*=-....这个不是特别懂 第一个是正常的,第二个是解对偶问题的 #include<cstdio> # ...
- 关于ExecuteNonQuery执行存储过程的返回值 、、实例讲解存储过程的返回值与传出参数、、、C#获取存储过程的 Return返回值和Output输出参数值
关于ExecuteNonQuery执行存储过程的返回值 用到过ExecuteNonQuery()函数的朋友们在开发的时候肯定这么用过. if(cmd.ExecuteNonQuery("xxx ...
- A bad vacation
My story happened in the winter of 2012, the first year I began to work in Beijing. It was a cold we ...
- ODB——基于c++的ORM映射框架尝试(使用)
摘要: 2.使用 首先,需要定义一个对象,用来和数据库字段对应: [cce lang=”cpp”] #ifndef VOLUME_H #define VOLUME_H #include #includ ...
- 杂项-Java:FreeMarker
ylbtech-杂项-Java:FreeMarker 1.返回顶部 1. FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源 ...
- matlab进入指定目录
cd C:\Users\hui\Desktop\minepy\1\minepy-1.2.0\minepy-1.2.0\matlab
- 栗染-Error parsing D:\sdkforas\android-sdk-windows\system-images\android-24\android-wear\x86\devices.xml
每次打开android virtual device manager 下面都会出现这样的问题 解决办法: 打开自己安装的sdk目录,找到/tools/lib/devices.xml去替换图中路径里面的 ...
- bzoj 1754: [Usaco2005 qua]Bull Math【高精乘法】
高精乘法板子 然而WA了两次也是没救了 #include<iostream> #include<cstdio> #include<cstring> using na ...
- SP1043 GSS1 - Can you answer these queries I(猫树)
给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M ...