JS对象之封装(二)
JS 对象封装的常用方式
1.常规封装
function Person (name,age){
this.name = name;
this.age = age;
}
Pserson.prototype = {
constructor:Person,
say:function(){
console.log('hello everyone!');
}
}
2.升级版 (较常见)
function Person (example){
this._init_(example);
}
Pserson.prototype = {
constructor : Person,
_init_ : function(example) {
this.name = example.name;
this.age = example.age;
}
say:function(){
console.log('hello everyone');
}
}
3.new 的执行原理
var myNew = function(constructor, args) {
var obj = {};
obj .__proto__ = constructor.prototype;
var res = constructor.apply(obj , args);
var type = typeof res;
if (['string', 'number', 'boolean', 'null', 'undefined'].indexOf(type) !== -1) {
return obj ;
}
return res;
}
解释说明: 通过var obj = {} 构造一个空对象. 将构造函数的原型属性prototype赋值给obj 的原型对象__proto__
,在执行 this.init(example); 这句话的时候,对象 obj 就可以在其原型对象中查找_init_ 方法。(原型链)。
var res = constructor.apply(obj,args);
以obj为上下文调用函数,同时将参数作为数组传递。那么,
this._init_(example);
就会被 obj 执行
函数
_init_ : function(example) {
this.name = example.name;
this.age = example.age;
}
以 obj 为上下文调用,o也将拥有自己的 name,age属性。
如果在构造函数中,return 复合类型,包括对象,函数,和正则表达式,那么就会直接返回这个对象,否则,返回 obj
var type = typeof res;
if(['string','number','boolean','null','undefined'].indexOf(type) !== -1){
return obj;
}
return res;
举例
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
console.log(this.name);
}
var jack = myFriend(Person, ['jack ']);
console.log(jack );
jack.say();
4.类jQuery 封装
jQuery 对象具有很强的集成性,可以作为函数调用,也可以做为对象调用,当作为函数调用的时候,可以无需 new 而返回一个实例。
代码
var Person = function(info){
return new Person.prototype.init(info);
}
Person.prototype = {
constructor: Person,
init:function(){
this.name = example.name.
}
}
Person.prototype.init.prototype = Person.prototype;
- 这种封装方式非常巧妙。 将对象的构造操作放在函数的里面,而自己充当一个工厂。 不断调用 prototype 并不是一个直观的做法,于是
var Person = function(example){
return new Person.fn.init(example);
}
Person.fn = Person.prototype = {
constructor: Person,
init:function(){
this.name = info.name;
this.say = function(){
this.makeExp();
}
}
makeExp:function(){
console.log(this.name);
}
}
// 虽然把makeArray 等常用方法挂载到 Person.prorotype 下面,但还是会被 init 这个实例使用.
Person.fn.init.prototype = Person.fn;
最后用 闭包 封装起来
var Person = (function(win) {
var Person = function(name) {
return new Person.fn.init(name);
}
Person.fn = Person.prototype = {
constructor: Person,
init: function(name) {
this.name = name;
this.say = function() {
this.makeExp();
}
},
makeExp: function() {
console.log(this.name);
}
}
Person.fn.init.prototype = Person.fn;
return Person;
})()
举例:
var people = Person('jack');
console.log(people);
people.say();
object.create();
一种构造对象的方式, 可以传递一个对象Person,构造一个people,并且使people 继承Person.
var Person = {
name: 'jack',
say: function() {
console.log(this.name);
}
}
var people = Object.create(Person);
console.log(people);
people.say();
对象Person的属性成为了people的原型属性,也就是说 people 原型继承自 Person !
我们可以实现一个 Object.create()
Object.create = function(prototype){
function Fun(){};
Fun.prototype = prototype;
var obj = new Fun();
return obj;
}
说明:
将 Person 作为 构造函数的 原型属性,就可以构造出 以Person 为原型对象的对象.
Object.create(原型); 创建一个继承该原型的实例对象
关于此方法的一些注意事项:
(1)若传参为Object.prototype,则创建的原型为Object.prototype,
- 和 new Object()创建的对象是一样的 Object.create(Object.prototype) <==>new
Object();
(2)若传参为空 或者 null,则创建的对象是没有原型的,
- 导致该对象是无法用document.write()打印会报错,
因为document.write()打印的原理是调用Object.prototype.toString()方法,
该对象没有原型,也就没有该方法,所以document.write()无法打印
由此延伸的知识点: 引用值都也是算作是对象, 所以都可以用document.write()打印; 原始值numebr, boolean,
string都有自己对象的包装类, 借助此机制也是可以用document.write()打印出的;
但undefined 和 null既不是引用值,也没有对应的包装类, 所以应该无法打印的,但大家会发现这两个值也是可是用document.write()打印的, 因为这两个值被设定为特殊值,
document.write()打印其是不用调用任何方法的,而是之直接打印其值
最新文章
- js键盘事件和焦点事件
- 第四天--html简易布局
- angularJS获取json数据(实战)
- Facebook的体系结构分析---外文转载
- hdr_beg(host) hdr_reg(host) hdr_dom(host)
- 关于全局变量和函数,在其他类中调用问题,extern关键字
- Android JIN返回结构体
- Qt之QCustomPlot绘图(一)配置和第一个例子
- 《转载》值得学习!Google的编程样式指南
- DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表
- 纯CSS3实现轮播图
- rabbitmq配置文件和站点管理(二)
- cocos2d-x初探
- python接口自动化(十六)--参数关联接口后传(详解)
- CentOS 6 RPM安装包下载地址
- Javascript 跨域知识详细介绍
- ORACLE procedure 一个参数分解成多个字符一点建议
- 利用maven将项目打包成一个可以运行的独立jar包
- BTrace使用简介
- sqlserver window身份验证时切换账户的快捷键
热门文章
- spring security记录
- 17)C++开始--命名空间
- 吴裕雄--天生自然C语言开发:错误处理
- 微信公众平台三种IP白名单场景及设置问题
- [LC] 513. Find Bottom Left Tree Value
- 96)PHP,文件上传(2)
- 使用 FreeMarker模板 Springboot 发送邮件
- C++对数组进行复制
- Java IO: FileOutputStream
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) P-Fear Factoring 区间内数的所有因数的和(除法分块)