美文网首页一个后端开发者的前端学习笔记
javascript 笔记03(创建对象/原型模式/js 继承/

javascript 笔记03(创建对象/原型模式/js 继承/

作者: Ethan_zyc | 来源:发表于2018-08-04 16:21 被阅读18次

js 笔记3

接笔记2

13.创建对象

  1. 工厂模式
function createNewObject(name, age, job) {
  let o = new Object();
  o.name = name;
  o.age = age;
  o.job = job
  o.sayName = function() {
    console.log(name);
  }
  return o;
};

let me = createNewObject('Ethan', 24, 'java');

console.log(me.name);  // Ethan
  1. 构造函数模式
function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function () {
    console.log(this.name);
  }
};

let p = new Person('Ethan', 24, 'java')

console.log(p.name);  // Ethan

以这种方式调用构造函数实际上会经历以下 4 个步骤:

  1. 创建一个新对象;
  2. 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
  3. 执行构造函数中的代码(为这个新对象添加属性);
  4. 返回新对象。

通过构造函数模式创建出来的 p 对象有一个 constructor 属性,该属性指向 Person。并且通过构造函数可以将实例标识为一种特定的类型,这是工厂模式做不到的。

console.log(p.constructor == Person); // true
console.log(p instanceof Person);  //true

如果不使用 new 来声明构造函数:this 就会指向 global 对象。

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

Person('zzz', 24, 'js');

global.sayName();

let o = new Object();

Person.call(o, 'yyy', 23, 'vue');

o.sayName();      // yyy
global.sayName(); // zzz

以上构造函数有个问题:使用构造函数的主要问题,就是每个方法都要在每个 实例上重新创建一遍 。

所以,做如下改进:

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

function sayName() {
  console.log(this.name);
}

let p1 = new Person('Ethan', 24, 'java');

p1.sayName();  // Ethan

let p2 = new Person('aa', 22, 'bb');

console.log(p1.sayName == p2.sayName);  // true,而用之前的方式结果为 false

14.原型模式

是什么:每个函数都有一个prototype(原型)属性,该属性可以看成一个指针,指向一个对象,这个对象的用途是包含了特定对象的所有实例共享的属性和方法。可以把prototype理解为通过构造函数而创建的那个对象实例的原型对象。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。所以,我们不必再构造函数中定义对象实例的信息,而是将这些信息直接添加到原型对象中。

因此,之前的构造函数可以写成这样:

function Person() {
};

Person.prototype.name = 'Ethan';
Person.prototype.age = 24;
Person.prototype.job = 'java';
Person.prototype.sayName = function () {
  console.log(this.name);
}

let p1 = new Person();

p1.sayName();  // Ethan

let p2 = new Person();

console.log(p1.sayName == p2.sayName); // true

理解:看图吧,构造函数、构造函数的对象、prototypeconstructor[[Prototype]](_PROTO_)之间的爱恨情仇。

image-20180804114016605

当我们调用一个对象的属性时,都会进行一次搜索,先搜索该对象是否有相同名称的属性,再去搜索该对象的原型是否有该属性。所以如果我们给一个对象的原型已经有的属性重新赋值,并不会影响对象的原型,只会应该该对象的属性。可以通过hasOwnProperty()来判断该属性是实例属性还是原型属性。还有一个方法是in,比如"name" in person1,这个方法不管该属性是在实例属性中还是原型属性中,都会返回true

除此之外,还有个方法返回对象所有的课枚举属性。

function Person() {
};

Person.prototype.name = 'Ethan';
Person.prototype.age = 24;
Person.prototype.job = 'java';
Person.prototype.sayName = function () {
  console.log(this.name);
};

let keys = Object.keys(Person.prototype);
console.log(keys);  // [ 'name', 'age', 'job', 'sayName' ]

当然,上面的原型语法比较复杂,可以写成下面这种相对简单的:

function Person() {
};

Person.prototype = { 
  // constructor: Person, // 最后一段话也可以用这行代替
  name: 'Ethan',
  age: 24,
  job: 'java',
  sayName: function() {
    console.log(this.name);
  }
};

// 因为每创建一 个函数,就会同时创建它的 prototype 对象,这个对象也会自动获得 constructor 属性,所以加上这个
Object.defineProperty(Person.prototype, "constructor", {
    enumerable: false,
    value: Person
});

原型模式的缺点:原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。 说简单点就是修改一个对象的属性会影响到另一个对象的该属性。


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

创建自定义类型最常用的方法,构造函数模式用来定义实例属性,原型模式用来定义方法和共享的属性。这样,每个实例都有自己的一份实例属性的副本,但同时又共享着对方法的引用,节省了内存。还可以向构造函数传递参数。

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

Person.prototype = {
  constructor: Person,
  sayName: function () {
    console.log(this.name);
  }
}

let p1 = new Person('aa', 10, 'java');
let p2 = new Person('bb', 20, 'js');

p1.sayName(); // aa
p2.sayName(); // bb

p1.name = 'cc';

p1.sayName(); // cc
p2.sayName(); // bb

16.js 中的继承

就说两种吧:

  1. 组合继承
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
};
function SubType(name, age){
//继承属性 SuperType.call(this, name);
    this.age = age;
}
//继承方法
SubType.prototype = new SuperType(); 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){
    alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
   alert(instance1.colors);
instance1.sayName();
instance1.sayAge();
//"red,blue,green,black"
//"Nicholas";
//29
 var instance2 = new SubType("Greg", 27);
alert(instance2.colors);
instance2.sayName();
instance2.sayAge();
//"red,blue,green"
//"Greg";
//27
  1. 更完善的:寄生组合继承
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
 };
function SubType(name, age){
    SuperType.call(this, name);
    this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    alert(this.age);
};

17.闭包

关于闭包,直接看这篇吧,我觉得说的挺易懂的。


18. BOM 中常用 api

window.innerHeigt

window.innerWidth

window.outerHeigt

window.outerWidth

window.location === document.location

location.assign

// 下面三行代码效果完全相同
window.location = "http://www.google.com";
location.href = "http://www.google.com";
location.assign = "http://www.google.com";

Navigator:获取浏览器的信息找这个。

screen:屏幕的信息找这个。

history.go(-1)

history.go(1)

history.back()

history.forward()

相关文章

  • javascript 笔记03(创建对象/原型模式/js 继承/

    js 笔记3 接笔记2 13.创建对象 工厂模式 构造函数模式 以这种方式调用构造函数实际上会经历以下 4 个步骤...

  • Js面向对象

    一、Js面向对象 二、Js原型及原型链 1、原型 JavaScript 的每个对象都继承另一个父级对象,父级对象称...

  • JavaScript进阶:原型模式

    1、前言 原型模式是指的将原型对象指向创建对象的类,使得不同的类共享原型对象的方法和属性。js中基于原型链的继承的...

  • 设计模式

    构造函数模式 利用原型继承的方式创建对象,以实现功能 混合模式 本质上也是利用原型继承的方式创建对象,但更加具象了...

  • 原型和原型链

    原型 javascript中每个JS对象一定对应一个原型对象,并从通过proto属性原型对象继承方法和属性 jav...

  • 关于JS中的原型和原型链

    目录 关于js 对象和原型 原型链 基于原型链的继承 参考资料ECMAScript 6 入门JavaScript原...

  • JavaScript 面向对象编程

    JavaScript 快速入门 面向对象编程创建对象构造函数忘记写new怎么办?原型继承class继承 面向对象编...

  • 原型模式(一)

    原型模式(一) 在Javascript中一切皆是对象,所以我们会创建很多对象。那么就来看看创建对象的方法.原型模式...

  • 2020-12-15

    js对象的创建和函数 创建对象 工厂模式 构造函数 原型方式+构造函数

  • 链式操作

    对象字面量创建对象 构造函数创建对象 构造函数和原型一起创建对象 参考 JavaScript设计模式 --- 方法...

网友评论

    本文标题:javascript 笔记03(创建对象/原型模式/js 继承/

    本文链接:https://www.haomeiwen.com/subject/tgemvftx.html