js构造函数详解

news2025/7/15 21:00:26

典型的面向对象编程语言(比如C++和Java),存在“类”(class)这个概念。所谓“类”就是对象的模板,对象就是“类”的实例。但是,在JavaScript语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)

‘面向对象编程’的第一步,就是要生成对象。而js中面向对象编程是基于构造函数(constructor)和原型链(prototype)的。

前面说过,“对象”是单个实物的抽象。通常需要一个模板,表示某一类实物的共同特征,然后“对象”根据这个模板生成。
js语言中使用构造函数(constructor)作为对象的模板,所谓构造函数,就是提供一个生成对象的模板,并描述对象的基本结构的函数。一个构造函数,可以生成多个对象,每个对象都有相同的结构。

对于JS中的任何一个普通函数,当用new关键字来调用时,它就是构造函数。可见与函数定义无关,与调用方法有关。在社区中,通常默契地将函数名首字母大写来表示该函数以后希望被作为构造函数来使用

作用:构造新对象,设置对象的属性和方法
ECMAScript提供了多个内置构造函数,如 Object、Array、String、Boolean、Number、Date…等等。
var obj = new Object();
var arr = new Array();
ECMAScript也允许自定义构造函数

构造函数一般首字母会大写,为了和普通函数区分
一个构造函数可以通过new创建多个实例对象
创建构造函数时,里面的属性和方法前必须加this,this就表示当前运行时的对象

    function Person(name, height) {
          this.name = name;
          this.height = height;
          this.bark = function(fs){
          return fs
         
      }
     }
  
      var boy = new Person('Keith', 180);
      console.log(boy);  //Person {name: 'Keith', height: 180, bark: ƒ}
      console.log(boy.constructor);  //f Person(){}  //整个构造函数原型
      console.log(boy.bark(8));  //8
      console.log(boy.name); //'Keith'
      console.log(boy.height); //180
 function Cat1(name){           
 this.name = name;
 console.log(this)  //先打印 new的时候打印  Cat1 {name: 'kk'}  
     }
 var cat3 = new Cat1("kk");
 console.log(cat3);   //后打印  Cat1 {name: 'kk'} 指向原型链,再赋值

构造函数的return

  function Dog(){
      this.name = "贝贝";
      this.bark = function(){
          console.log("汪汪汪");
      }
      // return 0;
      // return [];
  }
  var d1 = new Dog();
  console.log(d1);//Dog {name: '贝贝', bark: ƒ}
  //构造函数不需要return 就可以返回结果

return一个基本数据类型,结果不变,依旧返回一个对象
例:

return 0;
console.log(d1);//Dog {name: '贝贝', bark: ƒ}

return一个复杂数据类型,返回一个复杂数据类型
例:

return [];
console.log(d1);//[]

构造函数构造出的对象带有类型标识

console.log(p1)  
Person {
  name: 'zs',
  age: 12,
  eating: [Function: eating],
}  //打印结果有类型标识  //Person 就是类型标识


console.log(p1)
{name: 'zs', age: 12, eating:[Function: eating]} //无类型标识的

构造函数的原理(new之后发生了什么)
构造函数之所以能构造出对象,其实JS帮助我们做了很多骚操作。你以为new之后直接执行函数体代码,其实并不是,事实比我们看到了多了四步

在这里插入图片描述

1 自从用new调用函数后,JS引擎就会在内存中创建一个空对象{}
const newObj = {};
2 新对象的__proto__属性指向构造函数的原型对象
(通俗理解就是新对象隐式原型__proto__链接到构造函数显式原型prototype上。)

  newObj.__proto__ = functionName.prototype

3 构造函数内部的this会指向这个新对象(即将构造函数的作用域指向新对象)
this = newObj
4 从上到下执行函数体(只有这步是我们能直观看到代码的)
5 返回创造出来的对象(如果构造函数没有返回对象,则默认返回this。在函数体内部的this指向新创建的内存空间,默认返回 this 就相当于默认返回了该内存空间)

例子:

function Person(name, age) {
	this.name = name;
	this.age = age;
	this.eating = function() {
		console.log(this.name + ' is eating');
	}
}

const p1 = new Person('zs', 12);

//----------------------------------------------------------------------------
/*实际JS引擎帮助我们实现的操作*/
const newObj = {};
newObj.__proto__ = Person.prototype;
this = newObj;

this.name = name;
this.age = age;
this.eating = function() {
  console.log(this.name + ' is eating');
}

return newObj;

在构造函数原型上绑定方法节省空间

采用构造函数的确可以批量创建对象,且对象还都有该构造函数的logo,那么构造函数有什么缺点吗?有的。由于每次函数调用都会创建新的对象,对象中的函数(比如eating)也会创建多份,对于函数而言创建多份没有必要,能不能共用一个函数呢?

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

}

const p1 = new Person('zs', 12);


// 在函数原型上添加方法
Person.prototype.eating = function() {
	console.log(this.name + ' is eating'); // zs is eating
    return 5
}
console.log(p1.eating());  //5

将方法转移到构造函数原型上来定义后,对于实例对象p1,依然可以调用eating方法。调用p1的eating方法时,如果p1对象没有该方法,会去p1对象的原型对象p1.__proto_找,因为在构造p1时,绑定的原型:p1.__proto__ = Person.prototype,所以可以找到p1.__proto__.eating

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端基本知识介绍

目录 一.前端三剑客 1.前导 2.三剑客的分工 二.VsCode的介绍与配置 1.vscode的介绍 2.vscode的下载安装 3.vscode的使用 3.1 图形界面操作 3.3 常用插件 三.HTML基础标签 HTML基础知识 1.HTML为何物? 2.标签介绍 3.HTML属性 4.HTML标签骨架 基本的H…

微信小程序获取用户openid

小程序端直接获取: 实现代码:直接简单 wx.login({success(res) {if (res.code) {//发起网络请求wx.request({//这里填你自己的appid 和 wxspSecret url: "https://api.weixin.qq.com/sns/jscode2session?appid" wxspAppid"&secre…

2022年微信小程序授权登录的最新实现方案

微信授权登录 我们的项目开发有时候用到用户的一些信息,比如头像,昵称等。目前小程序为我们提供好了wx.getUserProfile方法以供获取用户信息,它的使用非常简单。 wx.getUserProfile方法获取用户信息 不推荐使用 wx.getUserInfo 获取用户信…

vue2.0运行导入的项目出现node:events:491 throw er; // Unhandled ‘error‘ event错误提示解决办法

只为记录自己遇到的错误。 错误提示: App running at: - Local: http://localhost:8080/ - Network: unavailable Note that the development build is not optimized. To create a production build, run npm run build. node:events:491 throw er…

微信小程序支付完整流程(前端)

微信小程序中,常见付款给商家的场景,下面列出企业小程序中,从0起步完整微信支付流程。 一,注册微信支付商户号(由上级或法人注册) 接入微信支付 - 微信商户平台 此商户号,需要由主管及更上级领导…

快速上手vue的登录界面(最新版)

文章目录一、创建vue项目二、引入依赖三、改造下项目四、写入Login视图总结这是一个非常非常适合新手的vue登录界面,总体来说美观大气,axios那部分没有发,有需要的大家可以自己进行二次开发,继续编写。 用到了技术栈有 vue/cli 5.…

vue3 | 数据可视化实现数字滚动特效

前言 vue3不支持vue-count-to插件,无法使用vue-count-to实现数字动效,数字自动分割,vue-count-to主要针对vue2使用,vue3按照会报错: TypeError: Cannot read properties of undefined (reading _c) 的错误信息。这个时…

idea如何导入jar包

通过添加Libraries的方式引入: 1、首先在根目录下创建一个 libs 的目录 2、打开 File -> Project Structure 3、单击 Libraries -> "" -> "Java" -> 选择我们导入的项目主目录,点击OK 4、注意:在弹出的方框…

Vite 完整版详解

目录 序论: vite架子分析 1、 打包构建: 2、环境变量 3、模式 4、兼容老浏览器 5、typescript相关 6、基本配置 核心配置全集 推荐两个插件插件Volar 、 Vue 3 Snippets 序论: 开发环境:ESMHMR:来实现模块的热更新;类…

前端项目性能优化方案有哪些

目录 一、 加载优化(减少http请求数) 二、图片优化 三、使用CDN 四、开启Gzip(代码压缩) 六、减少不必要的Cookie 七、脚本优化 八、前端代码结构的优化 九、SEO优化 一、 加载优化(减少http请求数&#xff09…

vue中axios的二次封装——vue 封装axios详细步骤

一、为什么要封装axios api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护。 通常我们的项目会越做越大,页面也会越来越多,如果页面非常的少,直接用axios也没有什么大的影响,那页面…

vue3的setup的使用和原理解析

1.前言 最近在做vue3相关的项目,用到了组合式api,对于vue3的语法的改进也是大为赞赏,用起来十分方便。对于已经熟悉vue2写法的同学也说,上手还是需要一定的学习成本,有可能目前停留在会写会用的阶段,但是s…

Swagger-的使用(详细教程)

文章目录前言一、简介二、基本使用1. 导入相关依赖2. 编写配置文件2.1 配置基本信息2.2 配置接口信息2.3 配置分组信息3. 控制 Swagger 的开启4. 常用注解使用ApiModelApiModelPropertyApiOperationApiParam5. 接口调用三、进阶使用1. 添加请求头四、项目下载前言 作为后端开放…

37.JavaScript对象与JSON格式的转换,JSON.stringify、JSON.parse方法的使用方法和注意事项

文章目录JSON处理JSON.stringifystringify的限制排除和替换映射函数格式化使用的空格数量自定义toJSON方法JSON.parse使用reviver总结JSON处理 JSON(JavaScript Object Notation)是JavaScript表达值和对象的通用数据格式,其本质就是符合一定…

2023前端面试题及答案整理(JavaScript)

JS类型 string,number,boolean,undefined,null,symbol(es6),BigInt(es10),object 值类型和引用类型的区别 两种类型的区别是:存储位…

Js各种时间转换问题(YYYY-MM-DD 时间戳 中国标准时间)

1. 类型总结 指定格式 YYYY-MM-DD HH:MM:SS时间戳中国标准时间 Sat Jan 30 2022 08:26:26 GMT0800 (中国标准时间) new Date()获得系统当前时间就会是这种形式 2. 类型之间的转换 时间戳转换为 yyyy-mm-dd或yyyy-MM-dd HH-mm-ss function timestampToTime(timestamp) {var …

【vue】 配置代理

文章目录参考文档跨域问题引入配置代理解决跨域问题:方法一:方法二:使用方法二最终的文件:总结参考文档 尚硅谷视频:https://www.bilibili.com/video/BV1Zy4y1K7SH?p95 axios官网教程:https://axios-htt…

uniapp分包,小程序分包处理,详解(图解),手把手从0开始

一、为什么要分包 因小程序有体积和资源加载限制,优化小程序的下载和启动速度。 二、主包和分包 所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据pages.json的配置进行划…

微信小程序详细教程(建议收藏)

一.小程序的开发准备 1. 小程序的安装与创建 第一步 打开小程序官网第二步 找到开发管理,找到开发设置,下面有一个AppID,复制即可,后面开发小程序需要用 新建项目 ,需要先下载微信开发工具下载网址,安装完…

九个前端神奇库,让你的前端项目瞬间美化,甲方看了都落泪

九个前端神奇库,让你的前端项目瞬间美化,甲方看了都落泪 九个前端神奇库 文章目录九个前端神奇库,让你的前端项目瞬间美化,甲方看了都落泪1. Lottie-web/Bodymovin2. Parallax.js3. Magic Grid4. webslides5. SVG.js6. rellax7. …