一、常见的创建对象的方式有3种:

① 声明变量的方式

var obj1 = { key1: "val1", key1: "val2", show: function () { console.log(this.key1) } }
var array = [1, 2, 3];

可以给 obj1 继续添加属性和方法,如:

obj1.color = "red";
obj1.hideen = function () { console.log("aaa") };

 使用操作符 new

var obj2 = new Object();

可以给 obj2 继续添加属性和方法,如:

obj2.name = "madom";
obj2.show = function () { console.log("aaa") };

③ 创建构造函数

function Cat() {             
  this.age = "18";
  this.show = function () {
    console.log(this.age);
  }
}

其实,构造函数 也是普通函数,只有当 new 操作的时候才是构造函数,

通过构 造函数 创建实例对象。每一个对象都有自己的内部原型 proto_

各个实例对象之间并不相同。

var cat1 = new Cat();
cat1.__proto__ === Cat.prototype; //true
var cat2 = new Cat();
cat2.__proto__ === Cat.prototype; //true
cat1 === cat2; // fals

再创建一个带有 return 的构造函数

function Bird() {
this.age = 19;
this.say = function () { console.log('my age is ' + 19) };
return {
name: 'Tim',
say: function () { console.log('hello ' + this.name) },
};
}

创建一个对象实例,看看有什么不同

var bird = new Bird();
bird.say(); // hello Tim
console.log(bird); // Object {name: "Tim", say: function}

发现:如果构造函数有 return,则对象实例无法使用构造函数 return 之前的属性和方法

new 操作时内部的运作大致如下:
第1步: 在内存中开辟一块空间。
第2步: 创建一个新空对象,并把 this 指向到这个空对象。
第3步: 把空对象的 内部原型 指向 构造函数的 原型对象。
第4步: 当构造函数执行完成后,如果 没有 return(返回值) 的话,则构造函数末尾存在 ‘隐式’ 的 return this;如果  return(返回值),则将返回值赋值给对象实例。

对创建实例的操作做如下模拟(非真实执行):

var cat = new Cat();
/* this = { };
* this._proto_ = Cat.prototype
* this = cat;
* return this
*/

二、实例的属性、方法 和 构造函数的属性、方法


每个实例都可以扩展自己的属性和方法

var cat = new Cat();
cat.sex = 'male';
cat.sing= function () {
console.log('喵...');
};
console.log(cat.sex); // male
console.log(cat.sing()); // 喵...

实例继承了构造函数的属性和方法,优先在 自身 找对应的属性和方法,没找到就到构 造函数 的 原型里 找;
如果给实例添加了与构造函数 同名的 属性和方法,如下:则自动 屏蔽 构造函数里的属性和方法;

var cat = new Cat();
cat.age = 20;
cat.show = function () {
console.log('I am a cat !')
};
console.log(cat.age); //
console.log(cat.show()); // I am a cat !

所以,建议 在原型里存公共的属性,常量,方法,对象实例会 共用 原型中的属性,常量,方法,这样可以节约内存的开销

function Dog( ) {
this.age = 2;
this.name = 'Tom';
}
Dog.prototype.show = function() {
console.log(this.age);
}

除了给对象实例扩展属性和方法,也可以给构造函数扩展属性和方法,当然也可以改写其属性和方法(对 js 内置对象的属性方法的修改需谨慎)

Dog.prototype.weight = "3kg"; // 增加属性
Dog.prototype.age = 99; // 修改属性
// 增加方法,修改方法同上

构造函数的用途就如工厂,输入对应的原材料,即可输出产品

// 创建“工厂”
function Dog( option ) {
this.age = option.age;
this.name = option.name;
}
Dog.prototype.show = function() {
console.log(this.name + ':' + this.age);
}
// 准备“材料”
var option1 = {
name: "Hapa",
age: 18
}
// 输出“产品”
var dog1 = new Dog(option1);
dog1.show(); // Hapa:18

构造函数的一种“流行”的写法(构造函数上只有函数调用,原型上写属性和方法)

Dog.prototype = {
_init: function ( option ) {
this.age = option.age || 3; // 如果 option 中没有属性 age,则默认 3
this.name = option.name || 'Bob'; // 如果 option 中没有属性 name ,则默认 "Bob"
},
show: function () {
console.log(this.age);
},
sing: function () {
    console.log('汪...');
  }
};

三、this 的指向,函数的四种调用模式


① 函数执行模式 

// 定义一个加法函数
function add(a, b) {
console.log(this === window); // true
return a + b;
}
// 调用此函数
add(1, 1); //

可以看出,函数执行模式中,this 指向 window。(其实 window.add(, ); 也是可以调用的,本质上也是对象方法调用模式)

② 对象方法调用模式

document.onclick = function () {
console.log(this === document); // true
}

所有的事件响应方法都是对象方法调用模式,在此不再列举了, dog.sing();中 this 指向 dog 这个实例,它们有个共同点,就是  "xxx.yyy()" 的格式

③ 构造器的调用模式 

// 构造函数
function Dog() {
this.age = 3;
this.show = function () {
console.log(Object.prototype.toString.call(this));
}
}
// 实例化一个 dog 对象
var dog = new Dog();
dog.show(); // [object Object]
console.log(Object.prototype.toString.call(Dog)); // [object Function]

dog 调用 show 方法时,打印出 this 是 一个 Object 对象,而 构造函数 Dog 打印出来是个 Function,所以 this 不是指向 Dog,this 的属性和方法对象实例 dog 都有,说明...

额~还没想好怎么证明 this 就是 dog ...

--- 知识在于分享,转载请注出处 ---

javascript 面向对象基础 (1)的更多相关文章

  1. 了解JavaScript 面向对象基础 & 原型与对象

    面向对象语言中的对象 老是能听到什么基于对象, 面向对象. 什么是对象, 如果有面向对象基础的人可以无视了, 下面举个简单的例子给大家讲讲面向对象中, 对象的定义, 这个是比较通用的, 不过对于JS来 ...

  2. JavaScript面向对象基础与this指向问题

      前  言           我们的程序语言经历了从"面向机器".到"面向过程".再到"面向对象"的一个过程.而JavaScript是一 ...

  3. Javascript面向对象基础(二)

    一: 用定义函数的方式定义类在面向对象的思想中,最核心的概念之一就是类.一个类表示了具有相似性质的一类事物的抽象,通过实例化一个类,可以获得属于该类的一个实例,即对象.在JavaScript中定义一个 ...

  4. javaScript面向对象基础

    最近学习了js的面向对象,为了能让自己更好的理解,这一篇博客就当作是加深自己学习印象的总结(可能会有很多不足,欢迎指正). js通过函数来创建对象,而且js本身也是一种对象,那么什么又是对象呢,对象包 ...

  5. javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)

    面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现.   工厂 ...

  6. JavaScript面向对象基础语法总结

    1.Javascript的 对象(Object): //例子:var car = { , , }; 2.使用构造函数来创建对象. //例子: var Car = function() { ; ; ; ...

  7. JavaScript基础精华02(函数声明,arguments对象,匿名函数,JS面向对象基础)

    函数声明 JavaScript中声明函数的方式:(无需声明返回值类型) function add(i1, i2) {             return i1 + i2;//如果不写return返回 ...

  8. JavaScript 面向对象开发知识基础总结

    JavaScript 面向对象开发知识基础总结 最近看了两本书,书中有些内容对自己还是很新的,有些内容是之前自己理解不够深的,所以拿出来总结一下,这两本书的名字如下: JavaScript 面向对象精 ...

  9. javascript的基础知识及面向对象和原型属性

    自己总结一下javascript的基础知识,希望对大家有用,也希望大家来拍砖,毕竟是个人的理解啊 1.1 类型检查:typeof(验证数据类型是:string) var num = 123; cons ...

随机推荐

  1. Kickstart无人值守安装系统

    1.导言 已经或未来将从事Linux系统运维工作的读者,经常会遇到一些机器式的重复的共走,例如:有时间同时上线几十甚至上百台服务器,而且需要我们在短时间内完成系统安装. q  光盘安装系统===> ...

  2. Struts2基础学习(五)—拦截器

    一.概述 1.初识拦截器      Interceptor 拦截器类似前面学过的过滤器,是可以在action执行前后执行的代码,是我们做Web开发经常用到的技术.比如:权限控制.日志等.我们也可以将多 ...

  3. AngularJS进入使用前的准备工作

    安装 AngularJS是以JavaScript文件形式发布的,可以通过 script 标签添加到网页中. 下载地址:https://github.com/angular/angular.js/rel ...

  4. 刷机无法连接4g

    只显示2g,gsm only 无法修改,本人刷cm13和lineageOs都遇到过这样的情况,可能与手机有关xt1570(moto x style),特在此分享,希望有用 1.首先在设置中将sim卡网 ...

  5. cocoapods安装好后repo换源

    1.pod repo 然后会出现以下内容,如下是我已经换了之后的,而你的URL还是github的 master - Type: git (master) - URL:  https://git.cod ...

  6. npm安装

    淘宝镜像http://npm.taobao.org/ $ npm install -g cnpm --registry=https://registry.npm.taobao.org mac下 sud ...

  7. jdk源码剖析五:JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)

    目录 1.背景 2.为什么废弃永久代(PermGen) 3.深入理解元空间(Metaspace) 4.总结 ========正文分割线===== 一.背景 1.1 永久代(PermGen)在哪里? 根 ...

  8. 容易产生错误的where条件

    错误的方式:$where = [];if ($type == 'wait') { $where['status'] = 0;}if ($type == 'done') { $where['status ...

  9. 封装类(Merry May Day to all you who are burried in work ~)---2017-05-01

    1.为什么要使用封装类? (1) 可以多个地方调用,避免代码的冗余 (2)面向对象三大特点之一,安全性高 2.代码及注意点? <?php class DB //文件名为:DB.class.php ...

  10. Sublime 3 如何使用列编辑模式

    前言 作为一名运维人员,文本IDE的列编辑模式对工作效率的提升很大.以前总用UE,觉得UE的列编辑模式设置很人性化(alt+c).后来接触了sublime,个人觉得它的列编辑模式使用对比UE略有差距. ...