资讯专栏INFORMATION COLUMN

JavaScript从初级往高级走系列————prototype

SKYZACK / 890人阅读

摘要:原文博客地址另一篇转载的从初级往高级走系列原型定义原型是对象的一个属性,它定义了构造函数制造出的对象的公共祖先。

原文博客地址:https://finget.github.io/2018/09/13/proto/

另一篇转载的JavaScript从初级往高级走系列————prototype

原型
定义: 原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。

用一张图简单解释一下定义。

每个函数上面都有一个原型属性(prototype),这个属性会指向构造函数的原型对象(Person.prototype)

每个函数的原型对象(Person.protorype)默认都有一个constructor属性指向构造函数本身(Person)

每个实例都有一个隐式原型(__proto__)指向构造函数的原型对象(Person.prototype)

每个原型对象也有隐式原型(__proto__)

// 构造函数
function Person() {
  this.LastName = "zhang"
}
// Person.prototype  --- 原型 (自带的,当定义了构造函数,它就孕育而生了)
// Person.prototype = {} --- 原型对象 是祖先
Person.prototype.name = "xiaoming";
var person = new Person()
var person1 = new Person()
console.log(person.name); // xiaoming (它自己没有,就会到原型(祖先)上去找)
console.log(person1.LastName); // zhang (它自己有,就会取自身的)
constructor
function Person() {
}
var person = new Person()
console.log(person.constructor) // function Person() {} 
// person自己没有constructor,所以继承至原型

Person.prototype:

图中浅紫色的都是自带的
function Person() {
}
function Car() {
}
Person.prototype.constructor = Car; // 改变constructor
var person = new Person()
console.log(person.constructor) // function Car() {}
proto
// __proto__
function Person() {
    
}
Person.prototype.name = "zhangsan"
var person = new Person()
console.log(person.__proto__)

new

New的过程

声明一个中间对象

将中间对象的原型指向构造函数的原型

将构造函数的this指向中间对象

返回中间对象,即实例对象

JavaScript —— New

function DNew() {
  // var obj = {}; // var obj = new Object() 创建一个空对象 
  // var obj = Object.create(null);
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  // obj.__proto__ = Constructor.prototype; 
  var obj = Object.create(Constructor.prototype);
  var result = Constructor.apply(obj, arguments); 
  return typeof result === "object" ? result || obj : obj; // 返回对象
}
在通过new 一个实例对象时:
function Person() {
  var this = {
    __proto__ : Person.prototype
  }
}

person.__proto__Person.prototype是指向同一个内存地址,这也就是 为什么实例没有属性或方法会到原型上去查找
function Person() {
    
}
Person.prototype.name = "zhangsan"
var person = new Person()
Person.prototype.name = "lisi"
console.log(person.name) // ???
function Person() {
    
}
Person.prototype.name = "zhangsan"
var person = new Person()
Person.prototype = {
  name : "lisi"
}
console.log(person.name) // ???
原型链

先扔一张图:

Person.prototype.__proto__ : Object.prototype

例子:

function Grand() {

}
Grand.prototype.lastName = "zhang"
var grand = new Grand()

function Father() {

}
Father.prototype = grand // Father的原型指向grand对象
var father = new Father()

function Son() {

}
Son.prototype = father // Son的原型指向father
var son = new Son()

上图中红线表示的就是原型链了
Object.create()
// Object.create(原型)
var obj = {name: "zhang",age: 23}
var obj1 = Object.create(obj)

Person.prototype.name = "zhang"
function Person() {}
var person = Object.create(Person.prototype)

Object.create(null),null就是一个空对象,没有原型。这也是·typeof null == "object"的原因
toString
undefinednull没有toString()
true.toString()

"abc".toString()

var num = 123
num.toString()
// 123.toString() 试一试会怎样

var obj = {}
obj.toString() // "[object Object]"

toString来自哪??

var num = 123
// num.toString(); --> new Number(num).toString()
// Number重写 toString
Number.prototype.toString = function() {}

// Number.prototype.__proto__ = Object.prototype
function Person(){}
Person.prototype.toString = function () {
  return "重写toString"
}
var person = new Person()
person.toString() // "重写toString"

// Object.prototype.toString
// Number.prototype.toString
// Array.prototype.toString
// Boolean.prototype.toString
// String.prototype.toString

toString隐藏功能:判断变量、对象的类型

call/apply
function Person(name, age) {
  this.name = name
  this.age = age
}
var person = new Person("zhang", 23)
var obj = {}
Person.call(obj,"wang",30) // this指向obj
// obj = {age:30,name:"wang"}
call/apply不仅改变了this的指向,还会执行对应的方法
var cat = {
  name: "咪咪"
}
function beatTheMonster(){
  console.log(this.name);
}
beatTheMonster.call(cat);

// 1.call 改变了this的指向。改变到了cat上。
// 2.beatTheMonster函数/方法执行了
// 3.bind(),保存了方法,并没有直接调用它
最后

创建了一个前端学习交流群,感兴趣的朋友,一起来嗨呀!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99509.html

相关文章

  • JavaScript初级高级系列————ES6

    摘要:采用二八定律,主要涉及常用且重要的部分。对象是当前模块的导出对象,用于导出模块公有方法和属性。箭头函数函数箭头函数把去掉,在与之间加上当我们使用箭头函数时,函数体内的对象,就是定义时所在的对象,而不是使用时所在的对象。 ES6 原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/ 现在基本上开发中都在使用ES6,浏览器环境...

    孙淑建 评论0 收藏0
  • JavaScript初级高级系列————异步

    摘要:之所以是单线程,取决于它的实际使用,例如不可能同添加一个和删除这个,所以它只能是单线程的。所以,这个新标准并没有改变单线程的本质。 原文博客地址:https://finget.github.io/2018/05/21/async/ 异步 什么是单线程,和异步有什么关系 什么是event-loop 是否用过jQuery的Deferred Promise的基本使用和原理 介绍一下asyn...

    andot 评论0 收藏0
  • JavaScript初级高级系列————MVVM-Vue

    摘要:原文博客地址如何理解如何实现是否解读过的源码与框架的区别实现实现独立初始化实例两者的区别数据和视图的分离,解耦开放封闭原则,对扩展开放,对修改封闭在中在代码中操作视图和数据,混在一块了以数据驱动视图,只关心数据变化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何实现 MVVM 是否解读过 ...

    codercao 评论0 收藏0
  • JavaScript初级高级系列————Virtual Dom

    摘要:当中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如。则就叫称为重绘。 原文博客地址:https://finget.github.io/2018/05/22/virtualDom/ 什么是虚拟DOM 用JS模拟DOM结构 DOM变化的对比,放在JS层来做(图灵完备语言) 提高重绘性能 重绘和回流 页面渲染过程:showImg(https://seg...

    tinyq 评论0 收藏0
  • JavaScript进阶之模拟new Object过程

    摘要:后续我将推出进阶系列,一方面是一个监督自己学习的一个过程,另一方面也会给看到的童鞋一些启发。第二步链接到原型中现在把构造函数和参数都打印出来了。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 写在前面的话 前端的入门相对简单,相对于其他方向天花板可能会相对较低。但是在市场上一个优秀的前端依旧是很抢手的。能够站在金字塔上的人往往寥寥...

    chengtao1633 评论0 收藏0

发表评论

0条评论

SKYZACK

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<