继承模式、命名空间、对象枚举
目录
一、继承模式
传统形式
借用构造函数
共享原型
圣杯模式
二、命名空间
使用命名空间实现属性私有化
使用闭包实现属性私有化
使用构造函数实现属性私有化
三、对象枚举
for in循环
hasOwnProperty方法
in操作符
instanceof操作符
一、继承模式
继承的发展史分为四个阶段:传统形式、借用构造函数、共享原型、圣杯模式(四种方法有利有弊,在最合适的地方用最恰当的方法)。
传统形式
传统形式指的是直接通过原型链实现继承。缺点是过多继承了没用的属性。这种方法很快就被废弃了。
Grand.prototype.lastName = "Ji";
function Grand () {}
var grand = new Grand();
//
Father.prototype = grand;
function Father(){this.name = "hehe";
}
var father = new Father();
//
Son.prototype = father;
function Son (){ }
var son = new Son();> son.name
< "hehe"
借用构造函数
借用构造函数实现继承是call和apply的实际应用。缺点有二:其一不能继承借用的构造函数的原型,其二每次执行构造函数都要多走一个函数,造成了资源的浪费。
function Person(name, age, sex){this.name = name;this.age = age;this.sex = sex;
}
function Student(name, age, sex, grade){Person.call(this, name, age, sex);this.grade = grade;
}
var student = new Student('li', 12, '男', 4);
共享原型
缺点:原型是公用的,不能在原型中添加个性化属性。
function Father () { }
function Son () { }
Son.prototype = Father.prototype; //Son和Father共用一个原型
var son = new Son();
var father = new Father();
//son和father共用一个原型
> Son.prototype.name = 'li';
> son.name
< "li"
> father.name
< "li"
//不能在原型中添加个性化属性
//将功能抽象出来,封装成一个函数
function inherit(Target, Origin){Target.prototype = Origon.prototype;
}
//第一种情况
> inherit(Son, Father);
> var son = new Son();
> son.lastName
< "deng"//第二种情况
> var son = new Son();
> inherit(Son, Father);
> son.lastName
< undefined //对象生成之后再设置共享原型,不会影响已经生成的对象,应为对象__proto__的指向不会改变
圣杯模式
圣杯模式解决了共享原型的弊端,即可以实现原型共享,又可以添加个性化属性。
function Son () { }
function Father () { }
//圣杯模式的核心代码
function F() { }
F.prototype = Father.prototype;
Son.prototype = new F();
//将圣杯模式抽象出来封装成一个函数
function inherit(Target, Origin){function F() { }F.prototype = Origin.prototype;Target.prototype = new F();Target.prototype.constructor = Target; //构造出的对象能找到自己的构造函数Target.prototype.uber = Origin.prototype; //构造出的对象能找到自己的超类-->超级父级,究竟继承自谁
}
> inherit(Son, Father);
> var son = new Son();
> var father = new Father();
> Son.prototype.sex = "male";
> son.sex
< "male"
> father.sex
< undefined
//雅虎提供的更合理的圣杯模式,利用闭包实现属性私有化
var inherit = (function () {var F = function () {}; //私有化变量,存储在闭包里。真实存在,但不能被外部主动访问return function(Target, Origin){F.prototype = Origin.prototype;Target.prototype = new F();Target.prototype.constructor = Target; Target.prototype.uber = Origin.prototype;}
}());
二、命名空间
本质:命名空间就是一个对象。
作用:管理变量,防止污染全局,适用于模块化开发。
使用命名空间实现属性私有化
var org = { //org就是一个命名空间department1 : { name : 'li'},department2 : { name : 'jiao'}
}
var dept1 = org.department1;
var dept2 = org.department2;
> dept1.name
< 'li'
> dept2.name
< 'jiao'
使用闭包实现属性私有化
将特定功能写到闭包里面,可以实现属性私有化,不会污染全局变量。存储在闭包里的私有化变量真实存在,但不能被外部访问。
var init = (function () {var name = 'abc';function callName(){console.log(name);}return function () {callName();}
}());
> init();
使用构造函数实现属性私有化
function Person(){//var this = { // eating: function(){ return parm; }//}var parm= "eat"; //构造函数私有属性,不能被外部访问,只能在构造函数内部使用this.name = "lilei" + parm;this.age = 13;this.eating = function(){return parm;}//return this; 构造函数私有化属性的本质是闭包
}
var obj = new Person();
obj.name; //"lileieat"
obj.eating(); //"eat"
obj.happy; //undefined, 构造函数的私有属性不能被外部访问
function Person(name){var a = 0;this.name = name;function func(){a++;console.log(a);}this.say = func;
}
var obj = new Person();
obj.say(); //1
obj.say(); //2
new Person().say(); //1
三、对象枚举
枚举就是遍历。
for in循环
for in可以遍历对象和数组。数组是一种特殊类型的对象,可以将数组的索引看作key值,将数组元素看作value。
var obj = {name : 'li',age : 12
}
for(var key in obj){ console.log(obj[key]);
}
< li
< 12
//key也可以写在外面
var key;
for(key in obj){ console.log(obj[key]);
}
for in循环不仅能遍历对象本身的属性,原型中的属性也能够遍历(Object.prototype中系统自带的属性除外,手动为Object.prototype添加的属性可以被for in遍历) 。
var obj = {__proto__ : {name : 'li',__proto__ : Object.prototype}
}
for(var key in obj){ console.log(obj[key]);
}
< li
obj.__proto__.__proto__.age = 12; //手动添加的属性可以被遍历
for(var key in obj){ console.log(obj[key]);
}
< li
< 12
hasOwnProperty方法
hasOwnProperty方法用于判断属性是否属于对象本身,返回true或false(原型中的属性不属于对象本身)。 一般hasOwnPrototype和for in配套使用。
for(var key in obj){if(obj.hasOwnProperty(key)){ //原型中的属性被排除console.log(obj[key]);}
}
< li
< 12
in操作符
in操作符用于判断对象能否访问某属性,包括原型中的。in操作符强调的是“对象能否访问”,hasOwnPrototype强调的是”对象是否拥有“。in操作符使用频率极低。
var obj = {name : 'li',__proto__ : {lastName : 'jiao'}
}
> 'name' in obj
< true
> 'lastName' in obj
< true
instanceof操作符
用法:A instanceof B
官方解释:用于判断A对象是不是B构造函数构造出来的。
本质:判断A对象的原型链上是否有B构造函数的原型
function Person () { }
var person = new Person();
> person instanceof Person
< true
> person instanceof Object
< true> [] instanceof Array
< true
> [] instanceof Object
< true
> {} instanceof Array
< false
区分变量是数组还是对象?
//第一种方法:利用instanceof操作符
> [] instanceof Array
< true
> {} instanceof Array
< false//第二种方法:利用constructor构造器
> var f1 = [].constructor; //f1 ---> function Array(){ }
> f1.name
> "Array"
> var obj = {};
> var f2 = obj.constructor; //f2 ---> function Object(){ }//第三种方法:利用Object.prototype.toString.call()
> Object.prototype.toString.call([]); // ---> '[object Array]'
> var obj = {};
> Object.prototype.toString.call(obj);// ---> '[object Object]'
Object.prototype.toString .call({})详解?
Object.prototype.toString是Object.prototype对象中的一个方法,对象中的方法在执行时this会指向调用该方法的对象。也就是说Object.prototype.toString方法里面必定有this,且this就是该方法要处理的对象。使用call将this指向指定的数据,就可以让数据被Object.prototype.toString方法处理。
继承模式、命名空间、对象枚举相关推荐
- javascript的对象创建模式---命名空间模式
javascript中对象的概念是很普遍的,对象是是对象,数组是对象,函数也是对象,字符串其实也是对象.常见的对象创建方法有对象字面量.构造函数创建.我们先来看看对象的创建还有哪些更高级的模式. 一. ...
- vue 对象继承_JS面向对象—对象的继承
面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过"类&qu ...
- 为什么你老是讲不清楚js的继承模式
作者:DBCdouble https://juejin.im/post/6869689622676471816 一.前言 相信很多人在遇到面试中都遇到过被问到过JavaScript继承模式的问题,都能 ...
- [导入]数据库物理模型设计的其他模式之继承模式
连载之7 原创:胖子刘(转载请注明作者和出处,谢谢) 数据库物理模型设计的其他模式 除了上面提到的四种主要设计模式,还有一些其他模式,在某些项目中可能会用到,在这里先简单做个说明,暂不做深入讨论,等到 ...
- javascript继承模式原理与示例深入剖析
原型链 ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法. 其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.简单回顾一下构造函数.原型和实例的关系:每个构 ...
- oncreate为什么一定要调用父类的oncreat_为什么你老是讲不清楚JS的继承模式
点击上方 "前端技术精选" 关注,星标或者置顶 17点30分准时推送,第一时间送达 作者:DBCdouble | 编辑:前端妹 来自:juejin.im/post/68696896 ...
- lombok使用中出现继承关系的对象时,出现的问题及解决办法
lombok使用中出现继承关系的对象时,出现的问题及解决办法 参考文章: (1)lombok使用中出现继承关系的对象时,出现的问题及解决办法 (2)https://www.cnblogs.com/h- ...
- js 原型prototype继承模式
js中利用原型prototype的方式实现继承是最常见的继承模式,如果让a的实例继承b,原型prototype的继承方式如下: function A(){} function B(){} A.prot ...
- 单继承模式下的JAVA和C++
总结:单继承模式下JAVA和C++相同,处理代码方面和事后处理方面有点小差异外没有什么本质的不同 JAVA一共3个文件 1.Base.class 2.Child.class(继承Base) 3._Ma ...
最新文章
- Chapter 2 Open Book——29
- C语言 什么时候用取地址什么时候不用取地址,符号讲解
- Python批量整理文件名小案例(附公众号第一批赠书活动中奖名单)
- 《JavaScript高级程序设计(第2版)》
- 令人深思的联系-this关键字(隐藏属性static)
- ansible获取服务器信息,ansible监控服务器资源使用
- 服务器安全配置常用软件
- windows虚拟显示器开发(二)WDDM hook(USB转HDMI驱动、USB手写屏开发)
- matlab double 取值,matlab定积分计算结果为表达式,我只想得到数值。用double(ans)也没用,不知道还有没有其他方法!...
- python计算金星凌日
- SpringCloud从0到丧心病狂
- 我的世界java版tp_神奇的tp指令 我的世界tp指令的用法
- 后台界面设计之表格设计
- (C语言)啥?4除以2等于0?
- java+web+股票图表_基于Echarts的股票K线图展示
- 基于JAVA影楼网站计算机毕业设计源码+系统+数据库+lw文档+部署
- 二〇二三-三-二十九
- dropbear:一个小巧的ssh server
- 用Node+wechaty写一个爬虫脚本每天定时给女(男)朋友发微信暖心话
- ppt上显示无法显示图片计算机可能,打不开电脑中的ppt文件并提示访问出错的解决方法...
热门文章
- log日志级别与简介
- 部队仓库管理系统有哪些功能和类型
- (Erlang语言)运行时中的无锁队列及其在异步线程中的应用
- 011:vue+openlayers加载引用bing地图(多种形式)
- 图片验证码识别软件实现自动打码HTTP接口说明
- 三星与红帽将在新一代存储器软件领域开展合作;华为MateView SE获全球首张低视觉疲劳显示器认证 | 美通企业日报...
- 驰名商标行政认定方式有哪些
- 【i.MX6UL试用体验】医疗监护仪制作(三)硬件
- SPARC中如何安装Linux系统(2)(转)
- Unity学习过程中需要用到GUI Texture组件,发现找不到,搜索之后了解该组件已过时,然后邂逅了csdn的Chit GPT