1. 基础✅
  2. prototype(✅)
  3. JS中的继承
  4. 使用JSON数据
  5. 构建对象实战

基础

关键字"this"指向了当前代码运行时的对象( 原文:the current object the code is being written inside )

定义template, 创建实际对象 object instances

constructor function:  JavaScript 用一种称为构建函数的特殊函数来定义对象和它们的特征。

当一个对象实例需要从类中创建出来时,类的构造函数就会运行来创建这个实例。

这种创建对象实例的过程称之为实例化-实例对象被类实例化

非经典的OOP:object-oriented programming

不像“经典”的面向对象的语言,从构建函数创建的新实例的特征并非全盘复制,而是通过一个叫做原形链的参考链链接过去的。(参见 Object prototypes),所以这并非真正的实例,严格的讲, JavaScript 在对象间使用和其它语言的共享机制不同。


传统写法:
必须写return xxxx

function createNewPerson(name) {
var obj = {};
obj.name = name;
obj.greeting = function() {
alert('Hi! I\'m' + this.name + ".")
};
return obj
}
创建一个constructor function
⚠️,构造器名字用首字母大写的name.
function Person(name) {
this.name = name;
this.greeting = function() {
alert('Hi! I\'m' + this.name + ".")
};
} 然后用构造器函数来创建一个实例
var person1 = new Person('Bob')

类似:new Vue({}) ; 实例化一个Vue对象。

需要⚠️:

创建新实例时,如果方法(这里是greeting)定义在构造器的函数体中,每次实例化都要定义这个方法,这不明智 ideal。

因此,使用prototype来定义函数。让实例继承这个方法就好, 这是构造器定义的定义约定。

Person.prototype.greeting = function() { ... }

小结:

多个创建object instance的方法:

  • 声明一个对象字面量 literal  (传统的方法)
  • 使用constructor function  (标准的方法)
  • 使用Object()构造器        
    • var person1 = new Object();
      然后再添加特性或方法,或者直接再new Object({添加}):
      person1.name = 'Chris';
      person1['age'] = 38;
      person1.greeting = function() {
      alert('Hi! I\'m ' + this.name + '.');
      };
  • 使用JS内建的create()方法:(用于继承)
  • 之前以及定义了person1对象
    
    使用create方法,继承了person1的特性和方法:
    (本质上是指定一个原型对象)
    var person2 = Object.create(person1);
    person2.name
    person2.greeting()  


Prototype

JS常常被描述为基于原型的语言。

每个对象都包含一个原型对象(我的理解就是类)。对象以其原型对象为模版,从原型对象继承方法和特性。

一个对象的原型对象也可以包含一个原型对象,从中继承方法和特性,层层类推。这涉及到原型链。prototype chain. (我的理解类似Ruby中的类的继承,形成一个祖先链。)

这就解释了为什么一个对象拥有定义在其他对象中的属性和方法,

因为这个对象继承了它的原型对象中的属性或方法。

对象和类:传统和JavaScript

  • 传统的OOP, 首先定义类,然后以此创建实例,类的属性和方法被复制到实例上(这和Ruby语法不一样)。
  • javascript, 在对象实例和它的构造器之间建立一个链接:__proto__属性, 之后通过上朔原型链prototype chain,在构造器中找到这些属性和方法。

  

使用JavaScript中的prototype

所有JS的函数有一个特殊的属性, prototype。

实例的_proto_属性就是它的构造器的prototype。(instance._proto_等于Constructor.prototype)

function doSomething() {};

doSomething.prototype.foo = "bar";
// 实例化doSometing函数
var instance = new doSometing();
// 给实例添加属性
instance.prop = 'hello'; //实例的_proto_属性就是它的构造器的prototype。

doSomething.prototype =>
{foo: "bar", constructor: ƒ}
instance.__proto__  =>
{foo: "bar", constructor: ƒ}

类似Ruby,通过_prop_这个链接向上级构造函数(类)找属性或方法

访问实例instance一个属性foo(instance.foo),如果实例属性中没有找到,则找它的构造器doSomething的prototype对象中的属性:

  • 如果找到,返回值。(这里的案例找到并返回“bar”)
  • 如果没有,浏览器就会上溯,去doSomething的prototype对象中的_proto_中找, 即它的原型window.Object的propotype中去找。

    • 如果还没找到,证明浏览器上所有声明了的_proto_上都不存在这个属性,返回undefined

⚠️,强调一下,方法和属性没有被copy,而是顺着prototype chain向上找,找到就引用。

function doSomething(){}
doSomething.prototype.foo = "barr";
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value"; 结果
"doSomeInstancing.prop: some value"
"doSomeInstancing.foo: barr"
"doSomething.prop: undefined"
"doSomething.foo: undefined"
"doSomething.prototype.prop: undefined"
"doSomething.prototype.foo: barr"

⚠️: obj._proto_ 方法,现在被Object.getPrototypeOf(obj)取代

小结:prototype对象:是继承成员被定义的地方。

  • 只有在prototype中被定义的属性/方法,才能够通过_proto_传递下去,被继承。
  • 那些非prototype属性/方法,不会继承。只能被构造器自身使用。

javascript实例复制他的构造函数对象中的prototype中的属性:

假设list是Person.prototype中的属性, 值是“apple”。person1是Person的实例:

  • read: (我的理解reference)调用person1.list,得到"apple"。这是person1实例通过原型链_proto_向上访问得到‘apple’值。
  • write:  (我的理解copy)调用person1.list = 'orange',list属性被copy到person1中。此时list:“orange”成为person1对象中的属性/值。

constructor属性

实例对象会从原型中继承一个constructor属性:该属性指向了用于构造次实例对象的构造函数。

person1.constructor返回构造person1实例对象的构造函数对象。

person2.constructor =>
ƒ Person(name){
this.name = name;
this.greeting = function() {
alert(this.name + "!!!")
};
}

因为返回构造器,可以利用这点新建一个实例对象:

var person3 = new person1.constructor("Snow")

另外,使用person1.constructor.name返回一个构造器的名字


修改原型

给构造器函数的prototype增加的方法, 都可以在它的实例中使用,这代表了继承。

总结:

构造器函数的建立方法:

  • 在函数体中定义属性
  • 在prototype中定义方法
// 构造器及其属性定义

function Test(a,b,c,d) {
// 属性定义
}; // 定义第一个方法 Test.prototype.x = function () { ... } // 定义第二个方法 Test.prototype.y = function () { ... } // 等等……

JS-Object(2) 原型对象 ,prototype属性。的更多相关文章

  1. 构造函数、原型对象prototype、实例、隐式原型__proto__的理解

    (欢迎一起探讨,如果有什么地方写的不准确或是不正确也欢迎大家指出来~) PS: 内容中的__proto__可能会被markdown语法导致显示为proto. 建议将构造函数中的方法都定义到构造函数的原 ...

  2. 275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法

    1.所有函数都有一个特别的属性 prototype : 显式原型属性 [普通构造函数的实例对象没有prototype 属性,构造函数有__proto__属性,原型对象有__proto__属性 ] 2. ...

  3. 原型对象prototype和原型属性[[Prototype]]

    构造器:可以被 new 运算符调用, Boolean,Number,String,Date,RegExp,Error,Function,Array,Object 都是构造器,他们有各自的实现方式. 比 ...

  4. js高级——构造函数,实例对象和原型对象——prototype、__proto__和constructor构造器

    一.前言 了解JavaScript面向对象,需要先了解三个名词: 构造函数,实例对象和原型对象. 注意:JavaScript中没有类(class)的概念,取而代之的是构造函数,两者类似却又有很大的差别 ...

  5. js原型对象中属性被覆盖(1)

    /**   *@author 程无衣   *@description 关于在原型对象中属性被覆盖   */       function Person(){}       Person.prototy ...

  6. [js高手之路]使用原型对象(prototype)需要注意的地方

    我们先来一个简单的构造函数+原型对象的小程序 function CreateObj( uName, uAge ) { this.userName = uName; this.userAge = uAg ...

  7. JavaScript的原型对象prototype、原型属性__proto__、原型链和constructor

    先画上一个关系图: 1. 什么是prototype.__proto__.constructor? var arr = new Array; 1. __proto__是原型属性,对象特有的属性,是对象指 ...

  8. 浅谈JS中的原型对象和原型链

    我们知道原型是一个对象,其他对象可以用它实现属性继承,除了prototype,又有__proto__ 1. prototype和__proto__的区别 prototype是函数才有的属性      ...

  9. JavaScript 的原型对象 Prototype

    在 JavaScript 中,每当定义一个对象(或函数)时候,对象中都会包含一些预定义的属性,其中一个属性就是原型对象 prototype. var myObject = function( name ...

  10. 【原型模式】--重写原型对象prototype的影响

    //[原型模式]--重写原型对象prototype的影响 2014-12-12//定义构造函数function Person() { }//直接指定构造函数的原型为一个对象(为了简化逐个给原型添加成员 ...

随机推荐

  1. 结合ajax 的表单验证

    浪费了我两天的时间 我也是醉了 html  结构 <!-- 密码修改 --> <div class="modal fade" id="operatePa ...

  2. EditPlus 中文版停止更新

    经过一段时间的考虑,我决定了终止 EditPlus 的中文版翻译工作. 感谢各位网友在这么长时间内对本汉化项目的关注.

  3. 20154312《网络对抗》Exp2 后门原理与实践

    常见问题快速链接 Handler failed to bind to xxx.xxx.xx.xxx:xxxx 使用Webcam_snap命令提示1411错误,无法正常拍照 常用后门工具实践 Windo ...

  4. c/c++日期时间处理与字符串string转换

    转自:https://www.cnblogs.com/renjiashuo/p/6913668.html 在c/c++实际问题的编程中,我们经常会用到日期与时间的格式,在算法运行中,通常将时间转化为i ...

  5. MySQL数据库----IDE工具介绍及数据备份

    一.IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 二.MySQL数据备份 # ...

  6. ACM题目———— 一种排序(STL之set)

    描述 输入 第一行有一个整数 0<n<10000,表示接下来有n组测试数据:每一组第一行有一个整数 0<m<1000,表示有m个长方形:接下来的m行,每一行有三个数 ,第一个数 ...

  7. ELK学习笔记之Logstash和Filebeat解析对java异常堆栈下多行日志配置支持

    0x00 概述 logstash官方最新文档.假设有几十台服务器,每台服务器要监控系统日志syslog.tomcat日志.nginx日志.mysql日志等等,监控OOM.内存低下进程被kill.ngi ...

  8. bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)

    P2061 [USACO07OPEN]城市的地平线City Horizon 扫描线 扫描线简化版 流程(本题为例): 把一个矩形用两条线段(底端点的坐标,向上长度,添加$or$删除)表示,按横坐标排序 ...

  9. 20145334赵文豪《网络攻防》 MSF基础应用

    实践目标 掌握metasploit的基本应用方式 掌握常用的三种攻击方式的思路. 实验要求 一个主动攻击,如ms08_067 一个针对浏览器的攻击,如ms11_050 一个针对客户端的攻击,如Adob ...

  10. 某模拟题(USACO部分题+noip2005部分题)

    题目描述 农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上.FJ有一辆拖拉机,也在农场上.拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内.拖拉 ...