js原型浅谈理解
之前在学习原型(prototype)的时候,一直对原型的理解不是很清晰,只是知道每个对象都有一个原型,然后在js中万物又皆对象。在这里谈一下自己对于js原型的简单理解吧。
原型可以实现属性和方法的共享。
原型链理解:
假设有一个对象o,其有自己的属性a和b:
{a:1,b:2};
然后o的原型o.[[prototype]]又有自己的属性b和c:
{b:3,c:4};
最后,o.[[prototype]].[[prototype]]为null。这就是原型链的末尾,即null,根据定义,null没有[[prototype]]
综上,整个原型链如下:
{a:1,b:2} ---> {b:3,c:4} ---> null;
console.log(o.a); // 1 a为o的自身属性
console.log(o.b); // 2 b为o的自身属性 但是o.[[prototype]]上面还有个b属性,但是它不会被访问到,这种情况称之为属性遮蔽(property shadowing)
console.log(o.c); // 4 c不是o的自身属性,那看看o.[[prototype]]上面有没有,在o.[[prototype]]上找到了c属性,那么c的值为4
console.log(o.d); // undefined 现在o上面找,没有d属性;再到o.[[prototype]]上面找,也没有;最后到o.[[prototype]].[[prototype]]上面找,
o.[[prototype]].[[prototyoe]]为null,停止寻找,返回undefined。
创建一个对象它自己的属性的方法就是设置这个对象的属性。唯一例外的获取和设置的行为规则就是当有一个 getter或者一个setter 被设置成继承的属性的时候。
继承方法:
JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别,包括上面的“属性遮蔽”(这种情况相当于其他语言的方法重写)。
当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。
var o = {
n:1,
m:function(){
return this.n + 1;
}
};
console.log(o.m()); // 2 当调用m方法时,this指向o;
var p = Object.create(o);
p.n = 10;
console.log(p.m()); // 11 调用m方法时,this指向当前调用它的p;
Object.create()创建一个新对象,新对象的原型就是调用时传入的第一个参数;
所以上面原型链为:
p ---> o ---> Obejct.prototype ---> null;
o继承了Object上面所有的属性和方法;所以对象所具有的属性和方法,o都可以使用;
对象具有hasOwnProperty()属性; 注意:hasOwnProperty() 判断的只是自己是否具有该属性或者方法 继承过来的属性和方法不算自身的;
hasOwnProperty 是 JavaScript 中唯一一个只涉及对象自身属性而不会遍历原型链的方法。
console.log(o.hasOwnProperty('m')); // true; o对象有自己的m方法
console.log(p.hasOwnProperty('m')); // false; p对象没有自己的m方法 它是继承自o的
var arr = [1,'str',true,o];
数组都继承自Array.prototype(indexOf,forEach等方法都是从它继承而来);
原型链如下:
arr ---> Array.prototype ---> Object.prototype ---> null;
function a(b){
return b;
}
函数都继承自Function.prototype(call,bind等方法都是继承而来);
原型链如下:
a ---> Function.prototype ---> Object.prototype ---> null;
使用构造器创建函数:
在js中,构造器其实就是一个简答的函数,当使用new操作符来操作这个函数时,它就可以被称为构造函数(构造方法);
function Person(){
this.eyes = [];
this.hands = [];
}
Person.prototype.addEyes= function(e){
this.eyes.push(e);
}
var p = new Person();
p是生成的对象,它自身有属性'eyes' 和 'hands',在p被实例化的时候,它的原型指向Person.prototype;
在用原型继承编写复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。此外,除非为了兼容新 JavaScript 特性,否则,永远不要扩展原生的对象原型。
js原型浅谈理解的更多相关文章
- 对js原型简单的理解和图解
对js原型简单的理解和图解 最近在努力的学习js中,今天就抽了个空把自己理解的原型,记下一下在笔记中,以后自己查看,有空在会把原型链记录一下. 1.prototype prototype:是一个函数的 ...
- Js之浅谈dom操作
JavaScript之浅谈dom操作 1.理解dom: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两 ...
- 谈谈我对 js原型链的理解
想要学习 “原型链” 必须要认识什么是 “原型” 和 “原型链” 先理解一下普通的继承和原型的区别,下面写一段js代码来帮助理解: var Animal = function(){ // 动物抽象类 ...
- JS原型链的理解和使用(一)
一些个人的理解,不一定是对的,仅供参考. 在JS中有函数和对象两个概念,而又有一切皆对象的概念及函数也是一个对象.所以可以说函数一定可以作为一个对象,而对象不一定是一个函数. 也可以说在js中对象分为 ...
- js原型链结构理解
在一般的面向对象的语言中,都存在类(class)的概念,类就是对象的模板,对象就是类的实例. 但在js中是没有类的定义的(万物皆是对象). 题外话:但是在ES6中提供了更接近传统语言的写法,引入了C ...
- JS原型链的理解和使用(二)
根据在创建对象的时候,创建出来的对象的__proto__指向创建这个对象的函数的prototype属性. 由于在调用对象的属性或者方法的时候会首先在对象的作用域中查找指定的属性或者方法,如果未找到则会 ...
- 对JS原型的一些理解
一.首先给出一道经典的原型题目: var F = function(){}; Object.prototype.a = function(){}; Function.prototype.b = fun ...
- js变量浅谈
js变量是除了this以外最让人恶心的东西了,还因为烂语法造成各种各样奇奇怪怪的事情发生,下面让我们来谈谈都有什么奇怪的事: 1.用var与不用var function test(){ a = 123 ...
- JS基础——浅谈前端页面渲染和性能优化
加载html中的静态资源 其中,加载静态资源的过程,一般为浏览器根据DNS服务器得到域名的IP地址,然后向这个IP的机器发送http请求,服务器收到.处理并返回http请求,浏览器得到返回http请求 ...
随机推荐
- 如何在Java 环境下使用 HTTP 协议收发 MQ 消息
1. 准备环境在工程 POM 文件添加 HTTP Java 客户端的依赖. <dependency> <groupId>org.eclipse.jetty</groupI ...
- Python一个简单的数据库类封装
#encoding:utf-8 #name:mod_db.py '''使用方法:1.在主程序中先实例化DB Mysql数据库操作类. 2.使用方法:db=database() db.fet ...
- C# base和this的用法
/** this关键字* this关键字引用类的当前实例* 注意:静态成员方法中不能使用this关键字,this关键字只能在实例构造函数.实例方法或实例访问器中使用*/ /** base关键字* ba ...
- 分表需要解决的问题 & 基于MyBatis 的轻量分表落地方案
分表:垂直拆分.水平拆分 垂直拆分:根据业务将一个表拆分为多个表. 如:将经常和不常访问的字段拆分至不同的表中.由于与业务关系密切,目前的分库分表产品均使用水平拆分方式. 水平拆分:根据分片算法将一个 ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 多版本
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 多版本 当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间 ...
- 【代码审计】iZhanCMS_v2.1 后台任意文件删除漏洞分析
0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...
- RF失败案例重跑
1.1 失败案例重跑 该功能主要是针对上次连跑失败的案例需要重新执行测试的情况,可自动识别上次执行失败的案例并进行重跑,无需手动选择相应的案例,简单高效. 1.5.1. 重 ...
- Linux 集群架构
集群介绍 Keepalived 配置高可用集群
- CDN的那些细枝末节
起源: 原本打算系统看看关于axios的介绍,无意中就看见一句"Using cdn",于是百度一下,"cdn"是什么? 名词解释:CDN CDN的全称是Cont ...
- 使用jsp实现文件上传的功能
首先是表单的jsp文件:upload.jsp <%@ page contentType="text/html;charset=UTF-8" language="ja ...