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

学习笔记:对象,原型和继承(1)

一:创建对象
1 工厂模式

 function createPerson(name, age, jod){
     var obj = new Object();
     obj.name = name;
     obj.age = age;
     obj.job = job;
     obj.sayName = function(){
         console.log(this.name);
     };
     return obj;
 }

 var person1 = createPerson('NEVAR', 23, 'Front-end Engineer');
 var person2 = createPerson('Amy', 27, 'Doctor');

2 构造函数模式

 function Person(name, age, job){
     this.name = name;
     this.age = age;
     this.job = job;
     this.sayName = function(){
         console.log(this.name);
     }
 }

 var person1 = new Person('NEVAR', 23, 'Front-end Engineer');
 var person2 = new Person('Amy', 27, 'Doctor');
 //person1和person2都是Person的不同实例。
 alert(person1.constructor == Person); //true
 alert(person2.constructor == Person); //true
 //即是Object的实例也是Person的实例
 alert(person1 instanceof Object); //true
 alert(person1 instanceof Person); //true
 //构造函数产生的是两个不同实例,同名函数是不相等的
 alert(person1.sayName == person2.sayName); //false

3 原型模式

 function Person(){
 }

 Person.prototype.name = 'NEVAR';
 Person.prototype.age = 23;
 Person.prototype.job = 'Front-end Engineer';
 Person.prototype.sayName = function(){
     console.log(this.name);
 };

 var person1 = new Person();
 person1.sayName(); //NEVAR

 var person2 = new Person();
 person2.sayName; //NEVAR

 console.log(person1.sayName == person2.sayName);// true

 var person3 = new Person();
 person3.name = 'PP';
 console.log(person3.name); //PP 来自实例

 delete person3.name;
 console.log(person3.name); //NEVAR 来自原型

 alert(person1.hasOwnProperty("name")); //false 来自原型
 alert(person3.hasOwnProperty("name")); //true  来自实例

 alert("name" in person1); //true in操作符的使用

 function hasPrototypeProperty (obj, name){
     return !obj.hasOwnProperty(name) && (name in obj)
 }
 //判断属性来自实例 真 然后取反 
 //并且name属性存在于obj原型链上 说明这个 属性是属于prototype的

 alert(hasPrototypeProperty(person1,'name')) // true
 alert(hasPrototypeProperty(person3,'name')) // false

 alert(Object.keys(Person.prototype)) //"name,age,job,sayName" 
 //Person的可枚举属性

不过以上方法太过于麻烦 每次都要写重复的prototype

 function Person(){
 }

 Person.prototype = {
     name : 'NEVAR',
     age : '23',
     job : 'Front-end Engineer',
     sayName : function(){
         console.log(this.name);
     }
 };

constructor 属性不再指向Person 了 指向Object

var friend = new Person();
 alert(friend instanceof Object); //true
 alert(friend instanceof Person); //true
 alert(friend.constructor == Person); //false
 alert(friend.constructor == Object); //true

于是可以这样

 Person.prototype = {
     constructor : Person,
     name : 'NEVAR',
     age : '23',
     job : 'Front-end Engineer',
     sayName : function(){
         console.log(this.name);
     }
 };

原型的动态性

var friend = new Person();

 Person.prototype.sayHi = function(){
     alert('Hi');
 }
friend.sayHi();//Hi
//这时没有问题,如果我们重写原型对象 那么情况就不一样了
function Person(){
}
var friend = new Person();
Person.prototype = {
constructor: Person,
name : "NEVAR",
age : 23,
job : "Front-end Engineer",
sayName : function () {
alert(this.name);
}
};
friend.sayName(); //error

重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系;它们引用的仍然是最初的原型。

原型模式也不是没有缺点。首先,它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值

对于那些包含基本值的属性倒也说得过去,毕竟(如前面的例子所示),通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出了

function Person(){
}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true

4组合使用构造函数模式和原型模式

 function Person(name, age, job){
     this.name = name;
     this.age = age;
     this.job = job;
     this.friends = ['Shelby','Court'];
 }
 Person.prototype = {
     constructor : Person,
     sayName : function(){
         console.log(this.name);
     }
 }

 var person1 = new Person('NEVAR', 23, 'Front-end Engineer');
 var person2 = new Person('Amy', 27, 'Doctor');

 person1.friends.push('Van');

 console.log(person1.friends) //'Shelby,Court,Van'
 console.log(person2.friends) //'Shelby,Court'
 console.log(person1.friends === person2.friends); // false
 console.log(person1.sayName === person2.sayName); //true

5动态原型模式
它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    if(typeof this.sayName != function){
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    }
}

 var person1 = new Person('NEVAR', 23, 'Front-end Engineer');
 friend.sayName();

6寄生构造函数模式

//不使用this和new
function Person(name, age, job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里添加私有变量和函数

    //添加方法
    o.sayName = function(){
        console.log(name);
    }
    return o;
}

注意,在以这种模式创建的对象中,除了使用sayName()方法之外,没有其他办法访问name 的值

相关文章:

  • JavaIO详解--快速学懂字节流与字符流
  • 搭建IM服务 so easy
  • JavaIO详解--尽可能将BIO、NIO、AIO讲得通俗易懂
  • 用jedis获取redis连接(集群和非集群状态下)
  • Mysql的索引调优详解:如何去创建索引以及避免索引失效
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • 经验分享:JAVA实习生刚进公司主要做些什么?以及进入职场后我的心理变化
  • oracle迁移mysql数据库注意(转)
  • 实习工作经历:代码在本地明明可以跑通,怎么放到服务器上就不行了呢?
  • 搭建一个包含多种Get请求和Post请求的工具类
  • 一致性hash原理与实现
  • 作为一个程序员需要了解多少网络方面的基础?网络基础总结(不断更新)
  • 四千字从源码分析ConcurrentHashMap的底层原理(JDK1.8)
  • redis学习笔记6--集合类型
  • 都2020年了,你还不知道count(1)和count(*)谁效率更高吗?
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 07.Android之多媒体问题
  • ES6简单总结(搭配简单的讲解和小案例)
  • Java 内存分配及垃圾回收机制初探
  • log4j2输出到kafka
  • python学习笔记 - ThreadLocal
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 回顾 Swift 多平台移植进度 #2
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 那些年我们用过的显示性能指标
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 如何用纯 CSS 创作一个货车 loader
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​虚拟化系列介绍(十)
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (3)选择元素——(17)练习(Exercises)
  • (论文阅读30/100)Convolutional Pose Machines
  • (译)2019年前端性能优化清单 — 下篇
  • (转)EOS中账户、钱包和密钥的关系
  • .net core开源商城系统源码,支持可视化布局小程序
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net 设置默认首页
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .NET微信公众号开发-2.0创建自定义菜单
  • @angular/cli项目构建--Dynamic.Form
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [Android Studio 权威教程]断点调试和高级调试
  • [BJDCTF2020]The mystery of ip1
  • [BUUCTF 2018]Online Tool(特详解)
  • [C++]——带你学习类和对象
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [ffmpeg] 定制滤波器