当前位置: 首页 > news >正文

js面向对象

创建对象的方法

1.字面量

// 优点:简单方便
// 缺点:每创建一个对象都要重新写,且创建多个比较占内存
var obj1 = {
    name: 'liuhui1'
};
var obj2 = new Object({
    name: 'liuhui2'
});
var obj3 = Object.create({
    name: 'liuhui3'
});

2.工厂模式

// 优点:改善了字面量方法创建多个相似对象的问题,不需要编写重复的代码
// 缺点:没有解决对象是别的问题,不知道对象的类型是什么
function person () {
    var obj = new Object();
    obj.name = 'liuhui4';
    obj.sayName = function () {
      console.log(this.name);
    };
    return obj;
}
var obj4 = person();
console.log(obj4.sayName());

3.构造函数模式

// 优点:创建并定义了对象类型的属性和方法,可以标示为特定的类型(自定义构造函数,原生:Object/Array)
// 缺点:方法没有被共享,每次实例一个对象都要重复绑定一个独立的方法
function Person (name) {
    this.name = name;
    this.sayName = function () {
        console.log(this.name);
    };
    this.newFun = newFun;
}
// 解决办法:将方法写在全局,但是就变成全局方法了跟封装的观念相违背了
// 新增代码
function newFun () {
    console.log('new name: ' + this.name);
}
var obj5 = new Person('liuhui5');
console.log(obj5.sayName());

4.原型模式

// 优点:将方法封装到相应的原型对象上,私有并实例可以共享这些属性和方法
// 缺点:所有属性和方法都共享了,改变实例的属性和方法会影响原型对象上的属性和方法
function Person1 () {

}
Person1.prototype = {
    constructor: Person1,
    name: 'liuhui6',
    sayName: function () {
        console.log(this.name);
    }
};
var obj6 = new Person1();
console.log(obj6.sayName());

5.组合模式(构造函数+原型模式)还没有完全理解

// 优点:构造函数用于定义实例属性和方法,原型模式用于共享定义的属性和方法
function Person2 (name) {
    this.newName = function () {
        console.log(name);
    }
}
Person2.prototype = {
    constructor: Person2,
    name: 'liuhui7',
    sayName: function () {
        console.log(this.name);
    }
};
var obj7 = new Person2();
var obj8 = new Person2('liuhui8');

继承的方法

1.借助构造函数实现继承

// 缺点:父级构造函数属性和方法没有被共享
function Parent1 () {
    this.name = 'parent1';
    this.play = [1, 2, 3];
}
function Child1 () {
    Parent1.call(this); // 关键:执行父级构造函数,深复制
    this.type = 'child1';
}
Parent1.prototype.say = function () {
    console.log('hello1');
};
console.log(new Child1());
var s1 = new Child1();
var s2 = new Child1();
s1.play.push(4);
console.log(s1.play, s2.play, s1.hasOwnProperty('play'), 'test1');

2.借助原型链实现继承

// 缺点:原型链上的属性和方法是共享
function Parent2 () {
    this.name = 'parent2';
    this.play = [1, 2, 3];
}
function Child2 () {
    this.type = 'child';
}
Parent2.prototype.say = function () {
    console.log('hello2');
};
Child2.prototype = new Parent2(); // 关键:将子级执行父级构造函数实现继承,浅复制
console.log(new Child2(), new Child2().say());
var s3 = new Child2();
var s4 = new Child2();
s3.play.push(4);
console.log(s3.play, s4.play, s3.hasOwnProperty('play'), 'test2');

3.组合方式

// 缺点:父级构造函数执行了两遍
function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
}
function Child3 () {
    Parent3.call(this); // 关键1
    this.type = 'child3';
}
Parent3.prototype.say = function () {
    console.log('hello3');
};
Child3.prototype = new Parent3(); // 关键2
var s5 = new Child3();
var s6 = new Child3();
s5.play.push(4);
console.log(s5, s6, s5.hasOwnProperty('play'), 'test');

4.组合方式优化1

// 缺点:实例属性constructor指向父级构造函数,使用instanceof不能正确判断对象类型
function Parent4 () {
    this.name = 'parent4';
    this.play = [1, 2, 3];
}
function Child4 () {
    Parent4.call(this);
    this.type = 'child4';
}
Parent4.prototype.say = function () {
    console.log('hello4');
};
Child4.prototype = Parent4.prototype;
Child4.prototype.constructor = Child4; // 新增代码,让实例指向其真实的构造函数
var s7 = new Child4();
var s8 = new Child4();
s7.play.push(4);
console.log(s7, s8);
// 判断是子原型Child4实例化还是Parent4直接实例化的
console.log(s7 instanceof Child4, s8 instanceof Parent4); // 判断不了
console.log(s7.constructor, s8.constructor, s7.hasOwnProperty('play'), 'test');

5.组合方式优化2

function Parent5 () {
    this.name = 'parent5';
    this.play = [1, 2, 3];
}
function Child5 () {
    Parent5.call(this);
    this.type = 'child5';
}
Parent5.prototype.say = function () {
    console.log('hello5');
};
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
var s9 = new Child5();
var s10 = new Child5();
s9.play.push(4);
console.log(s9 instanceof Child5, s9 instanceof Parent5);
console.log(s9.constructor, s10.constructor, s9.hasOwnProperty('play'), 'test11');

参考

  • 构造函数的继承
  • 非构造函数的继承

相关文章:

  • 【转载】xtrabackup原理及实施
  • 在Android应用程序中实现推送通知
  • Hbase源码分析:Hbase UI中Requests Per Second的具体含义
  • LINUX KERNEL SPINLOCK使用不当的后果
  • android——Tinker启蒙,献给热修复一脸懵逼的自己
  • Spring Boot——2分钟构建spring web mvc REST风格HelloWorld
  • python 模块包裹
  • no.6 字符串和格式化输入/输出02
  • 从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理
  • jquery操作字符串常用方法总结及工作代码
  • retrofit post请求多文件,partMap用法
  • 【转载】Etcd+Confd实现Nginx配置文件自动管理
  • C#编程(五十五)----------HashSet和SortedSet
  • 云非万能!云计算不能解决的三大问题
  • maven打包加速(转) (开启多线程,之前发现只占用一核CPU100%,其他CPU闲置的情况)...
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • es的写入过程
  • Java 多线程编程之:notify 和 wait 用法
  • java2019面试题北京
  • LeetCode18.四数之和 JavaScript
  • Python - 闭包Closure
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 编写高质量JavaScript代码之并发
  • - 概述 - 《设计模式(极简c++版)》
  • 关于 Cirru Editor 存储格式
  • 关于for循环的简单归纳
  • 看域名解析域名安全对SEO的影响
  • 实现简单的正则表达式引擎
  • 一个SAP顾问在美国的这些年
  • ionic入门之数据绑定显示-1
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​iOS安全加固方法及实现
  • # 数论-逆元
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .net 程序发生了一个不可捕获的异常
  • .NET 反射的使用
  • .NET 命令行参数包含应用程序路径吗?
  • .netcore 获取appsettings
  • .net操作Excel出错解决
  • .NET成年了,然后呢?
  • .NET导入Excel数据
  • .Net的DataSet直接与SQL2005交互
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .NET中 MVC 工厂模式浅析