构造函数与原型链和面向对象的学习(一)

2023-05-16

什么是构造函数

构造函数就是一个普通的函数,里面可以写任何语句(逻辑语句或DOM操作)  ,可以new出新的实例,使其实例可以共享构造函数的原型

第一个例子

    function Fun() {
      this.name = "小明";
      this.age = 12;
      this.sex = "男";
      console.log("aa")//"aa""
    }
    var obj = new fun();
    console.log(obj.age); //12

 用new运算符调用一个函数的时候,会经历四步走(简洁版本

  1. 创建新对象 ;
  2. 给新对象的内部属性赋值,关键是给[[Prototype]]属性赋值(默认为字符串‘proto’),构造原型链(如果构造函数的原型是 Object 类型,则指向构造函数的原型;不然指向 Object 对象的原型);
  3. 执行构造函数 ,执行过程中内部 this 指向新创建的对象 o
  4. 如果 构造 内部显式返回对象类型数据,返回该数据,执行结束;不然返回新创建的对象

注意第四步:当构造函数自己有return的时候:当构造函数中自身的retuen的是数值那么只是会结束函数执行,但是返回值还是那个定义的{},如果自带的return是一个函数,那么返回的是那个自带的函数

1.一般我们可以用new来多次调用一个函数,总可以得到具有相同属性群的对象,但不相同,
          

    if (obj === obj2) {
      console.log("相等");
    } else {
      console.log("不相等");
    }

这里返回不相等因为虽然他们都是调用的同一个函数中生产的对象但他们的堆地点是不同的(引用类型也就是对象他们的值相同不代表他们就相同他们的位置还不一样);

图片理解


2.new就是一个运算符并不是c c++ java中的类的概念
3.构造函数就是一个普通的函数,里面可以写任何语句(逻辑语句或DOM操作)     

    if (this.age < 18) {
      console.log("未成年");
    } else if (this.age > 18) {
      console.log("成年");
    } else {
      console.log("请输入年龄");
    }

上文就用到了if语句 来判断age对象中的age属性的值;

4.上面讲到new四步走中:所有语句执行后,函数retum这个对象;(上面的例子将函数返回给力obj他现在是个对象了);但当函数中写了return会怎么样?
如果ruturn 的是一个基本类型那么忽视这个return,但return一样会会阻止构造函数return后面语句的执行

    this.name = "小明";
    this.age = age;
    if (this.age < 18) {
      console.log("未成年");
    } else if (this.age > 18) {
      console.log("成年");
    } else {
      console.log("请输入年龄");
    }
    return 3;   //这里的3不会返回,但sex属性也没用了,aa也不会输出因为被return阻止了
    this.sex = "男";
    console.log("aa")//"aa""

如果ruturn 的是一个引用类型那么原有的return对象会被覆盖   

    function fun2(name, age) {
      this.name = name;
      return { "a": 1, "b": 2 };
      this.age = age;
    }
    var xiaoming = new fun2("小明", 12);
    console.log(xiaoming); //{a: 1, b: 2} 原来的return对象就被覆盖了
    这里就有把return设置为{ } (构架函数的工厂模式四步走)
    function People(name, age) {
      var obj = {};
      obj.name = name;
      obj.age = age;
      return obj;
    }
    var xiaoming = new People("小明", 12);
    console.log(xiaoming);

注意

1.当我们设置prototype为非对象类型

如果构造函数的原型不满足形成原型链的要求,那就跳过直接和内建对象原型关联

重写构造函数原型属性为非对象类型,实例内部 Prototype 属性指向 Object 原型对象
因为实例是一个对象类型的数据,默认会继承内建对象的原型,

function Foo(name) {
  this.name = name;
}

var o1 = new Foo("xiaoming");
console.log(o1.__proto__ === Foo.prototype); // true


Foo.prototype = 1;
var o2 = new Foo("xiaohong");
console.log(o2.__proto__ === Foo.prototype); // false
console.log(o2.__proto__ === Object.prototype); // true

2. 构造函数执行返回结果是对象的情况

手写new

  1.     创建新对象
  2.     给新对象的内部属性赋值,关键是给[[Prototype]]属性赋值(默认为字符串‘proto’),构造原型链(如果构造函数的原型是 Object 类型,则指向构造函数的原型;不然指向 Object 对象的原型);// 这一条是创建新Object的规则
  3.     执行构造函数,将其构造函数中的this设置为第一步创建中的新对象
  4.     判断构造函数的返回值,如果返回值是对象类型(instanceof Object === true)就返回函数返回值,否则返回创建的新函数
    function createNew() {
      // 获取构造函数
      const Fun =  Array.prototype.shift.call(arguments)
      // 1
      const obj = new Object()
      // 2
      Object.setPrototypeOf(obj, Fun.prototype)
      // 3
      let res =  Fun.apply(obj, arguments)
      // 4
      return res instanceof Object ? res : obj
    }

优化

警告: 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.__proto__ = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。

    const isObject = function (obj) {
      // return obj.toString() = "[object objrect]"
      return obj instanceof Object
    }

    let myNew =  function (fn, ...args) {
        
      //  第一条和第2条合并
      let obj = isObject(fn.prototype) ? Object.create(fn.prototype) : Object.create(Object.prototype)

      let res =  fn.apply(obj, args)

      return  isObject(res) ?  res : obj
    }

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构造函数与原型链和面向对象的学习(一) 的相关文章

  • table-call布局

    学习了旭哥的文章总结 等分 lt style gt container display table height 300px width 100 border 1px solid red child display table cell b
  • css小测--两栏布局

    目标效果 这个题得分我是6分中国题是针对表格布局 xff0c flex布局 xff0c inline block布局 xff0c absolute布局来完成 xff0c 大家突然问题来了为什么没float xff0c 嗯 xff0c 这个看
  • Vue $nextTick

    使用场景 1 当改变了DOM中的数据后 xff0c 立马去获取DOM中的数值 2 当我们在watch侦听器中改变了数据 xff0c 立马用这一些数据去做一些操作 xff0c 这里为什么不可以呢 xff1f 因为watch其实应该也算是会被推
  • javaScript 快速排序

    简单理解 首先我觉得我们要明确一般算法都是需要递归的 xff0c 所以我们首先完成第一循环 第一个循环我们找到一个主元 xff08 数组的中间 xff09 xff0c 我们把大于的放右边 xff0c 小于的放左边 然后在分别把主元左边的和右
  • for..in 和 for..of的区别

    in xff1a 支持IE6 43 xff08 老 xff09 枚举对象枚举字符串 xff08 IE9 43 后支持 xff09 枚举数组 xff0c 但是数组只身的方法 xff0c 和原型上的方法也会枚举出来 xff0c xff08 可以
  • 垂直水平居中的方法

    垂直水平居中 HTML解构 lt div class 61 34 container 34 gt lt div class 61 34 box box 11 34 gt 1 lt div gt lt div gt lt div class
  • line-height理解

    行高的单位 百分比 xff1a 突出了行高和字体大小的基佬关系当字体行高的单位为百分比的时候 xff0c 行高以字体大小为依据 em xff1a em这个单位 xff0c 当作用在行高的时候是以当前文字大小为依据 xff0c 当作用在字体大
  • 剖析Vue数据劫持的实现原理

    原文 xff1a https github com DMQ mvvm xff08 包含原文源码 xff09 由于源码的注释比较少 xff0c 我自己加了注释的地址 xff1a https github com zengqingxiao MV
  • css弹性动画

    通过css让生硬的动画变得更加自然 下面我们会通过javaScript和css分别实现 效果图 xff1a 我们知道没一个物体运动都有一个运动轨迹 xff0c 例如上面的小球是模拟的弹簧运动从而让动画更加自然 xff0c 而上图的运动轨迹图
  • C#利用服务器实现客户端之间通信

    这篇文章主要为大家详细介绍了C 利用服务器实现客户端之间通信 xff0c 感兴趣的小伙伴们可以参考一下 先来讲述下我自己对于整个Socket通信过程的理解 xff0c 毕竟初学 xff0c 说错见谅 xff0c 知道错了会改正 1 首先在服
  • js中的节流和防抖

    在学习Element ui源码的过程中有注意到题目使用的节流防抖居然是引用的一个npm包 xff0c 而不是自己写的一个utils为什么我会这样想呢 xff0c 因为在看Data组件的时候E没有使用一些常见的比如 moment 这样的组件库
  • 设计模式

    订阅发布者 事件监听 xff0c 发布 class Pubsub constructor this handles 61 事件的订阅 64 param String type 发布的事件类型 64 param Function handle
  • JS中的变量提升和函数提升问题

    学习完后的总结 Js代码分为两个阶段 xff1a 编译阶段和执行阶段 Js代码的编译阶段会找到所以的申明 xff0c 并用合适的作用域将他们关联起来 xff0c 这个是词法作用域的核心内容 包括变量申明和函数声名都会在代码被执行前的编译阶段
  • this的由来

    JS的数据结构 xff1a var obj 61 foo 5 面的代码将一个对象赋值给变量obj JavaScript 引擎会先在内存 xff08 堆 xff09 里面 xff0c 生成一个对象 foo 5 xff0c 然后把这个对象的内存
  • div中动态文字内容的处理(内容在文字少的时候文字居中,在文字多的时候局左)

    如何实现板块中的内容在文字少的时候文字居中 xff0c 在文字多的时候局左 HTML lt div class 61 34 box2 34 gt lt p class 61 34 content 34 gt 当文字少的时候 lt p gt
  • css流体布局下发宽度分离原则与box-sizing的使用

    学习完了CSS世界的总结 因为默认的box sizing 为content box宽度作用在内容 所以当出现 box width 100px border 1px solid red 或 box width 100px padding 20
  • css任意高度收缩动画技术

    弹性动画学习 学习css世界后 xff1a 利用max height和overflow hidden来实现 HTML lt div class 61 34 box 34 gt lt input id 61 34 check 34 type

随机推荐

  • 学校CSS世界第三章总结

    1 块级元素 块级元素并不等于display xff1a black xff1b li的默认display xff1a list item xff1b table的display默认是table xff1b 他们都符合块级元素的基本特征 x
  • padding属性详细分析

    lt p gt 1 padding会增加元素的尺寸 lt p gt lt p gt 2 padding对内联元素的影响 xff0c 对内联元素的垂直方向的影响是有的但视觉是没有 lt p gt lt a href 61 34 javasvr
  • 利用margin来实现两端对起

    为什么会对齐一般我们给li标签设置margin left最后一个总是会有一个不需要的left那为什么如何去除呢 xff1f 答案是 xff1a margin xff1a 负值 如果ul右边多了20px xff0c 那么给ul设置个margi
  • 裸机通过u盘以hostengine的方式成功安装ovirt4.5

    本次安装是在两台服务器上进行 xff0c 采用hostengine的方式安装 xff0c 也就是一台机上先安装oVirt node xff0c 再安装oVirt engine xff0c 另外一台机安装oVirt node xff0c 并加
  • 关于paddin-bottom的中的未定义的问题

    css世界的学习后 xff1a padding的兼容问题一般遇不到 xff0c 滚轮什么时候出现 xff1a Chrome浏览器的滚轮是在子元素超过content box的时候显示 xff1b IE Firefox是在超过padding b
  • 流动性的深入学习

    何为 34 流 34 流 61 文档流 xff1b 当我们在一个容器中倒入足量的水时 xff0c 水一定会均匀平铺整个容器 所以流动性也就是100 自适应 但width 61 100 xff01 61 流动性自适应100 原因 xff1a
  • 如何用border来画三角形

    学习总结 HTML lt div class 61 34 son 34 gt lt div gt CSS son width 0px border 20px solid border color black transparent tran
  • window和document的区别

    window对象 它是一个顶层对象 而不是另一个对象的属性 xff0c 即浏览器的窗口 document 当前显示的文档 该属性本身也是一个对象
  • JS距离的理解

    偏移量 offsetWidth 元素在水平方向上占用的空间大 xff0c 包括元素的宽度 可见的垂直滚动条宽度 左边框高度和右边框高度 offsetWidth 61 width 43 padding 43 border offsetHeig
  • 汉堡按钮的制作以及其中的问题

    第一种自己写的 xff0c 下面的第二种是网上的用一个span使用做出来的 HTML lt div class 61 34 box 34 gt lt chang用来判断是否变换 gt lt span class 61 34 s1 34 gt
  • 对js动画和时间控制的使用

    JavaScript Document 打算移动的元素ID xff1b elementID 该元素的目的地的 34 左 34 位置 xff1b final x 该元素的目的地的 34 上 34 位置 xff1b final y 停顿时间 x
  • css动画小结

    一 转换 transform IE9 43 1 旋转rotate transform rotate 30deg ms transform rotate 30deg IE 9 webkit transform rotate 30deg Saf
  • Django 判断访问来源是PC端还是手机端

    pc or mobile py 判断访问来源是pc端还是手机端 import re def judge pc or mobile ua 34 34 34 param ua 访问来源头信息中的User Agent字段内容 return 34
  • 圆形进度条是学习

    学习网站 xff1a http www cnblogs com jr1993 p 4677921 html CSS margin 0px padding 0px box margin 50px auto 0 width 300px heig
  • 定位插件

    写了个等位插件 xff0c 点击nav中的LI xff0c 位移 xff08 与href有视觉效果 xff09 到达相应板块 xff08 这里的类比li中的类中多了个H字母 xff09 的位置 lt li class 61 34 wz 34
  • JQ复习

    一选择器 1 基本选择器 2 层级选择器 3 过滤选择器 first 选取第一个元素 last 选择最后一个元素 not 去除所有与给定选择器匹配的元素 39 input not first 39 even选取索引是偶数的元素 xff0c
  • 第7章艺术编程Ajax的学习

    终于学到Ajax以前一直没接触到一直以为很NB xff0c 对这些内容我基本上是个小白中的小白哎 xff0c 继续加油 Ajax可以做到只更新页面的一下部分 xff0c 其他部分不需要重新加载 下面就是根据书上的内容所写 HTML lt d
  • 函数是否加括号的问题

    lt a onclick 61 34 fun 34 gt lt a gt 这里有括号 document getElementById 34 ID 34 onclick 61 fun 这里不可以有括号 为什么会有这样的不同 首先加上括号是执行
  • this的详细分析加案例

    this对象是在函数运行时候基于函数的执行环境 xff08 上下文 xff09 绑定的 方法调用模式函数调用模式改造器调用模式apply call bind调用模式 1 方法调用模式 函数有所属对象 xff0c 也就是这个函数是myObje
  • 构造函数与原型链和面向对象的学习(一)

    什么是构造函数 构造函数就是一个普通的函数 xff0c 里面可以写任何语句 逻辑语句或DOM操作 xff0c 可以new出新的实例 xff0c 使其实例可以共享构造函数的原型 第一个例子 function Fun this name 61