当前位置: 首页 > 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(*)谁效率更高吗?
  • 【347天】每日项目总结系列085(2018.01.18)
  • 0基础学习移动端适配
  • CSS 专业技巧
  • HTTP中GET与POST的区别 99%的错误认识
  • MYSQL 的 IF 函数
  • React中的“虫洞”——Context
  • VUE es6技巧写法(持续更新中~~~)
  • vue-cli3搭建项目
  • vue-cli在webpack的配置文件探究
  • Vue小说阅读器(仿追书神器)
  • 闭包--闭包之tab栏切换(四)
  • 从零开始在ubuntu上搭建node开发环境
  • 官方解决所有 npm 全局安装权限问题
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 跨域
  • 浅谈Golang中select的用法
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 项目管理碎碎念系列之一:干系人管理
  • 一些css基础学习笔记
  • 一些关于Rust在2019年的思考
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #微信小程序(布局、渲染层基础知识)
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)linux 命令大全
  • .form文件_SSM框架文件上传篇
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .net流程开发平台的一些难点(1)
  • .net生成的类,跨工程调用显示注释