三、js笔记

news2025/2/3 20:50:23

(一)JavaScript概述


1、发展历史

  • ScriptEase.(客户端执行的语言):1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言)
  • Javascript:Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本语言.Sun和Netscape共同完成.后改名叫Javascript
  • Jscript:微软随后模仿在其IE3.0的产品中搭载了一个JavaScript的克隆版叫Jscript.
  • EcmaScript规范:为了统一三家,ECMA(欧洲计算机制造协会)定义了ECMA-262规范.国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 作为标准(ISO/IEC-16262)。从此,Web 浏览器就开始努力(虽然有着不同的程度的成功和失败)将 ECMAScript 作为 JavaScript 实现的基础。EcmaScript是规范. 

2、JavaScript组成

ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:

  • 核心(ECMAScript) 
  • 文档对象模型(DOM) Document object model (整合js,css,html)
  • 浏览器对象模型(BOM) Broswer object model(整合js和浏览器) 

注:Javascript 在开发中绝大多数情况是基于对象的,也是面向对象的


(二)ECMAScript


包含内容:

  • 语法 
  • 类型 
  • 语句 
  • 关键字 
  • 保留字 
  • 运算符 
  • 对象 (封装 继承 多态) 基于对象的语言.使用对象.

1、JavaScript的引入方式

使用<script>标签,写在哪个位置都行,一般放在body最后,因为加载顺序从上到下,放在前面标签还没加载找不到,放最后标签已经加载了,更好找到标签

1.1 嵌入式 

<script>
    /*这里直接编写js代码,如:alert('hello yuan')*/
</script>

 1.2 导入式(推荐)

<script src="hello.js"></script>  // src是js文档的路径

2、Javascript语法 

2.1 变量

  • js变量是弱类型,声明变量时不区分数据类型,统一用var关键字声明变量,如:var a;
  •  可以声明变量的同时赋值,一行可以声明多个变量(以逗号,分隔),并且可以是不同类型,如:var name="张三", age=18, job="lecturer";
  • (了解) 声明变量时 可以不用var. 如果不用var 那么它是全局变量,但推荐都使用var关键字声明变量,效率更高,也能避免一些问题。
  • 还可以用let关键字声明块作用域变量(更推荐):
    • 只在声明它所在的块(由 {} 包围的代码块)、语句或表达式内部有效。
    • 同一作用域内,不能使用 let 重复声明同一个变量名,如果尝试这样做,将会引发一个错误。
    • 暂时性死区:变量声明之前的作用域范围内,该变量是不可访问的,尝试在声明之前访问 let 变量会引发一个 ReferenceError
    • 虽然 let 声明的变量会被提升到它们所在的作用域顶部,但是在变量声明之前的任何访问都会因为暂时性死区而失败。
    • 在循环中的特殊行为‌:let 在循环内部声明变量时(特别是 for 循环),每次迭代都会为该变量创建一个新的绑定。这意味着循环体内的每个变量都是独立的,并且具有自己的值。
      /*例子:let 如何提供块作用域,并且如何在不同的块中独立地声明和使用变量。*/
      {
        let x = 10;
        console.log(x); // 输出 10
      }
      console.log(x); // ReferenceError: x is not defined
      
      let y = 20;
      {
        let y = 30; // 这是一个新的块作用域内的 y
        console.log(y); // 输出 30
      }
      console.log(y); // 输出 20,外部的 y 没有被内部的 y 影响
      
      // 在循环中使用 let
      for (let i = 0; i < 3; i++) {
        console.log(i); // 分别输出 0, 1, 2
      }
      console.log(i); // ReferenceError: i is not defined,因为 i 只在循环块内有效
      
  • 变量命名,首字符只能是字母,下划线,$美元符 三选一,且区分大小写,x与X是两个变量。
  • 变量还应遵守以下某条著名的命名规则:
    • Camel 标记法(小驼峰式):首字母是小写的,接下来的字母都以大写字符开头。例如:var myTestValue = 0, mySecondValue = "hi";
    • Pascal 标记法(大驼峰式):首字母是大写的,接下来的字母都以大写字符开头。例如:Var MyTestValue = 0, MySecondValue = "hi";
    • 匈牙利类型标记法:在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,则:Var iMyTestValue = 0, sMySecondValue = "hi";

2.2 常量

常量 :直接在程序中出现的数据值,或使用const关键字声明的变量,不可被修改和重新赋值 

2.3 基础规范 

  • js代码每个语句后要有语句结束标志——分号;
  • 但如果一个语句写一行的话,不加分号也不会有问题,因为js会自动把换行符视为这一行结束;
  • 但如果语句结束不加分号也不换行就写别的语句,那就报错了
  • 注释:
    • 单行注释://
    • 多行注释:/* */
  • 使用{}来封装代码块,如:
    • function f(参数列表){函数体}
    • if (条件语句){代码块}

2.4 标识符 

  • 标识符: 
    • 由不以数字开头的字母、数字、下划线(_)、美元符号($)组成
    • 常用于表示函数、变量等的名称
    • 例如:_abc,$abc,abc,abc123是标识符,而1abc不是
    • JavaScript语言中代表特定含义的词称为保留字,不允许程序再定义为标识符

2.5 数据类型 

  • 基本类型(数据存储在栈内存):数字类型(Number)、字符串(String)、布尔型(Boolean)、Null、Undefined
  • 引用类型(数据存储在堆内存,把指向堆内存地址的引用存储在栈内存):对象(object)、数组、函数
  • 类似python的字典在js中是object类型:不同于python中的字典,js中a={name:"alex"}就相当于a={"name":"alex"},取值方法为a.name或a["name"]
 (1)数字类型(Number)
  • 最基本的数据类型
  • 不区分整型数值和浮点型数值
  • 所有数字都采用64位浮点格式存储,相当于Java和C语言中的double格式
  • 能表示的最大值是±1.7976931348623157 x 10308 
  • 能表示的最小值是±5 x 10 -324  
  • 在JavaScript中10进制的整数由数字的序列组成:
    • 精确表达的范围是:-9007199254740992 (-253) 到 9007199254740992 (253)
    • 超出范围的整数,精确度将受影响
  • 浮点数:
    • 使用小数点记录数据,例如:3.4,5.6
    • 使用指数记录数据,例如:4.3e23 = 4.3 x 1023
  • 16进制和8进制数的表达:
    • 16进制数据前面加上0x,八进制前面加0
    • 16进制数是由0-9,A-F等16个字符组成
    • 8进制数由0-7等8个数字组成
    • 16进制和8进制与2进制的换算:
      # 2进制: 1111 0011 1101 0100   <-----> 16进制:0xF3D4 <-----> 10进制:62420
      # 2进制: 1 111 001 111 010 100 <-----> 8进制:0171724
(2)字符串(String) 
  • 是由Unicode字符、数字、标点符号组成的序列
  • 字符串常量:首尾由单引号或双引号括起的字符序列
  • JavaScript中没有字符类型
  • 常用特殊字符在字符串中的表达:
    • 字符串中部分特殊字符必须加上反斜杠\,如Unicode字符\u4f60
    • 常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线
(3)布尔型(Boolean) 
  • Boolean类型仅有两个值:true和false,也代表1和0,实际运算中true=1,false=0
  • 布尔值也可以看作on/off、yes/no、1/0对应true/false
  • Boolean值主要用于JavaScript的控制语句,例如:
    if (x==1){
        y=y+1;
    }else{
        y=y-1;
    }
(4)Null & Undefined 
  •  Null 类型:只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的
  • Undefined 类型只有一个值,即 undefined:
    • 当声明的变量未初始化时,该变量的默认值是 undefined
    • 当函数无明确返回值时,返回的也是值 "undefined"
  • 尽管这两个值相等,但它们的含义不同:
    • undefined 是声明了变量,但未对其初始化时赋予该变量的值;
    • null 则用于表示尚未存在的对象,如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。
    • typeof null的结果是object
(5)对象object 
  • 在JavaScript中,对象(Object)是一种包含多个键值对(key-value pairs)的数据结构。
  • 每个键值对将一个键(也称为属性名)映射到一个值。
  • JavaScript对象具有动态性,可以在运行时添加、修改或删除属性,而不需要预先定义对象的结构,这有助于JavaScript对象处理复杂和多变的数据。
  • 对象是JavaScript编程中的核心概念之一,广泛用于存储和管理复杂的数据。
let person = {
  firstName: "John",
  lastName: "Doe",
  age: 30,
  isStudent: false,
  courses: ["Math", "Science", "History"],
  address: {
    street: "123 Main St",
    city: "Anytown",
    state: "Anystate",
    zipCode: "12345"
  },
  greet: function() {
    console.log("Hello, my name is " + this.firstName + " " + this.lastName);
  }
};
/*示例中,person 对象包含了多个属性:

firstName 和 lastName 是字符串类型的属性,分别存储人的名和姓。
age 是数字类型的属性,存储人的年龄。
isStudent 是布尔类型的属性,表示该人是否为学生。
courses 是数组类型的属性,存储该人参加的课程列表。
address 是另一个对象类型的属性,包含街道、城市、州和邮政编码等子属性。
greet 是一个方法(函数),当调用时,会打印出一个问候消息。
你可以通过以下方式访问和操作对象的属性:
*/

// 访问属性
console.log(person.firstName); // 输出 "John"
console.log(person["lastName"]); // 输出 "Doe"
console.log(person.address.city); // 输出 "Anytown"

// 修改属性
person.age = 31;
console.log(person.age); // 输出 31

// 调用方法
person.greet(); // 输出 "Hello, my name is John Doe"

// 添加新属性
person.email = "john.doe@example.com";
console.log(person.email); // 输出 "john.doe@example.com"

// 删除属性
delete person.isStudent;
console.log(person.isStudent); // 输出 undefined,因为属性已被删除
 (5.1)创建对象:对象字面量

最简单和最常用的方法,只需用花括号 {} 包围一组键值对即可

let obj = {
  key1: "value1",
  key2: "value2",
  key3: 3,
  key4: true,
  key5: function() {
    console.log("This is a method!");
  }
};
(5.2)创建对象:Object 构造函数

使用 new Object() 来创建一个空对象,然后添加属性。 

let obj = new Object();
obj.key1 = "value1";
obj.key2 = "value2";
// ...
 (5.3)创建对象:Object.create() 方法

创建一个拥有指定原型和属性的对象,其中第一个参数是现有对象的原型,还可以传递一个描述符对象来添加或修改新对象的属性。

let proto = {
  greet: function() {
    console.log("Hello!");
  }
};
let obj = Object.create(proto);
obj.key1 = "value1";
// ...
(5.4)创建对象:自定义构造函数‌ 

自定义一个构造函数,然后使用 new 关键字来创建对象实例

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    console.log("Hello, my name is " + this.name);
  };
}

let person1 = new Person("John", 30);
let person2 = new Person("Jane", 25);
(5.5)创建对象:class 关键字‌(ES6引入) 

定义一个类,然后使用 new 关键字来创建类的实例。这是ES6及更高版本中推荐的方式,因为它提供了更清晰和更结构化的方式来定义对象和其行为。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log("Hello, my name is " + this.name);
  }
}

let person1 = new Person("John", 30);
let person2 = new Person("Jane", 25);
(5.6)创建对象:工厂函数 

不使用 new 关键字就能创建对象的方法,通常返回一个包含所需属性和方法的普通对象。 

function createPerson(name, age) {
  return {
    name: name,
    age: age,
    sayHello: function() {
      console.log("Hello, my name is " + this.name);
    }
  };
}

let person1 = createPerson("John", 30);
let person2 = createPerson("Jane", 25);
(5.7)注意事项 
  • 每种方法都有其适用的场景和优缺点。
  • 通常,对于简单的对象,使用对象字面量是最方便的。
  • 对于需要多个实例的对象,使用构造函数或类可能更合适。
  • 工厂函数则提供了一种更加灵活和不需要 this 绑定的创建对象的方式。 

2.6 数据类型转换 

  • JavaScript属于松散类型的程序语言:
    • 变量在声明的时候并不需要指定数据类型
    • 变量只有在赋值的时候才会确定数据类型
    • 表达式中包含不同类型数据则在计算过程中会强制进行类别转换:
      • 数字 + 字符串:数字转换为字符串

      • 数字 + 布尔值:true转换为1,false转换为0

      • 字符串 + 布尔值:布尔值转换为字符串true或false

2.7 强制类型转换函数 

  • 函数parseInt:强制转换成整数,例如:
    • parseInt("6.12")=6 ;
    • parseInt(“12a")=12 ;
    • parseInt(“a12")=NaN ;  // NAN:意思是not a number,当强转数字时遇到不属于数字的字符时,会转换数字失败,如果前面有数字,截取前面的数字为结果,否则哪怕后面再有数字,值为NAN,属于Number类型
    • parseInt(“1a2")=1
  • 函数parseFloat:强制转换成浮点数,例如:parseFloat("6.12")=6.12
  • 函数eval:将字符串强制转换为表达式并返回结果,例如:
    • eval("1+1")=2 ;
    • eval("1<2")=true

2.8 类型查询函数(typeof) 

  • ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内,(string / number / boolean / object )。
  • 可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。 
  • 例如:
    • typeof("test"+3)   // "string";
    • typeof(null)  // "object ";
    • typeof(true+1)  // "number";
    • typeof(true-false)  // "number"

2.9 ECMAScript 运算符 

(1)ECMAScript 算数运算符
  • 加(+)、 减(-)、 乘(*) 、除(/) 、余数(% )  加、减、乘、除、余数和数学中的运算方法一样  例如:9/2=4.5,4*5=20,9%2=1

  • -除了可以表示减号还可以表示负号  例如:x=-y

  • +除了可以表示加法运算还可以用于字符串的连接  例如:"abc"+"def"="abcdef"

  • 递增(++) 、递减(--):

    • 假如x=2,那么x++表达式执行后的值为3,x--表达式执行后的值为1

    • i++相当于i=i+1,i--相当于i=i-1

    • 递增和递减运算符可以放在变量前也可以放在变量后:

      • i++,++在后,先取后加,即先把i本来的值作为表达式的值,i的值再自增1,如i=1, i++的表达式值=1,计算后i=2;

      • ++i,++在前,先加后取,即i先自增1,再作为表达式的值,如上文的i,++i的表达式值=3,计算后i=3;

      • i--,--在后,先取后减,即先把i本来的值作为表达式的值,i的值再自减1,如上文的i,i--的表达式值=3,计算后i=2;

      • --i,--在前,先减后取,即i先自减1,再作为表达式的值,如上文的i, --i的表达式值=1计算后i=1

  • 一元加减法:
    • -a:负号,把a变成负值;
    • +a:对a做类型转换;
    • a="yuan";a=+a;alert(a);  // 结果显示a的值为NaN,属于Number类型的一个特殊值,当遇到将字符串转成数字无效时,就会得到一个NaN数据
    • NaN特点: NaN参与的所有的运算都是false,除了!=是true外,如:
      • var n=NaN;
      • alert(n>3); // false
      • alert(n<3); // false
      • alert(n==3); // false
      • alert(n==NaN); // false
      • alert(n!=NaN); // true
(2)ECMAScript 逻辑运算符 

与 (&&) 、或(||) 、非(!):

  • 与(&&)运算符:全真即真
    • 运算数可以是任何类型的,不止是 Boolean 值。
    • 如果某个运算数不是原始的 Boolean 型值,&&运算并不一定返回 Boolean 值:
      • 如果某个运算数是null,返回 null;
      • 如果某个运算数是NaN,返回 NaN;
      • 如果某个运算数是undefined,返回undefined;
      • 如果一个运算数是对象,另一个是boolean值,返回该对象;(除了Boolean、null、NaN和undefined都是对象)
      • 如果两个运算数都是对象,返回第二个对象。
  • 或(||)运算符:全假即假,但与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑或 运算并不一定返回 Boolean 值
  • 非(!)运算符:真即假,假即真
(3)ECMAScript位运算符 
  • 按位与&:二进制形式分别按照每一个位对应做与运算,都是1得1,否则得0,如:
    1&2=0
    0001
    0010
    ————
    0000
  • 按位或|:二进制形式分别按照每一个位对应做或运算,都是0得0,否则得1,如:
    1|2=3
    0001
    0010
    ————
    0011
  • 按位异或^:二进制形式分别按照每一个位对应做异或运算,只要位不同结果为1,否则结果为0,如:
    1^2=3
    0001
    0010
    ————
    0011
  • 左移<<:二进制形式每个位数字左移多少位,后面补0,如:
    3<<2=12
    0011
    ————
    1100
  • 右移>>:二进制形式每个位数字右移多少位,前面补0,如:
    12>>1=6
    1100
    ————
    0110
  • 取反(NOT)~:二进制形式每个位数字1变成0,0变成1,如;
    ~6=9
    0110
    ————
    1001 
(4)ECMAScript 赋值运算符 

赋值运算符=:JavaScript中一个等号=代表赋值,两个等号==表示判断是否相等(与c、c++、java、python中类似)

  • 配合其他运算符形成的简化表达式,例如:i+=1相当于i=i+1,x&=y相当于x=x&y 
(5)ECMAScript等性运算符 
  • 执行类型转换的规则如下:
    • 如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
    • 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。 
    • 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。 
    • 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。 
  • 在比较时,该运算符还遵守下列规则:
    • 值 null 和 undefined 相等。 
    • 在检查相等性时,不能把 null 和 undefined 转换成其他值。 
    • 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。 
    • 如果两个运算数都是对象,那么比较的是它们的引用值。
    • 如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
(6)ECMAScript 关系运算符(重要) 

等于 ( == )  、全等(===)、不等于( != ) 、不全等(!==)、 大于( > ) 、 小于( < ) 大于等于(>=) 、小于等于(<=),比较规则如下:

  • 比较运算符两侧如果一个是数字类型,一个是其他类型,会将其类型转换成数字类型,转换失败就是NaN
  • 比较运算符两侧如果都是字符串类型,比较的是最高位的ascII码,如果最高位相等,继续取第二位比较. 
  • 全等(===)和不全等(!==)不会做类型转换,相当于其他语言如python的==和!=
(7)Boolean运算符(重要) 

经常用于条件判断、控制流语句(如if语句)以及逻辑运算中,以帮助程序根据条件执行不同的代码块,包括:

  • 逻辑运算符与(&&)、或(||)、非(!)
  • 空值合并运算符(??(ES2020引入):
    • 当左侧的操作数为nullundefined时,返回右侧的操作数;
    • 否则,返回左侧的操作数。 
  • 可选链运算符(?.)(ES2020引入):
    • 用于安全地访问对象的深层属性;
    • 当访问的属性不存在时,不会抛出错误,而是返回undefined

注:if的条件语句中[];0; null; undefined;object(new Object()创建的对象);都会判断为false

var temp=new Object();// false;[];0; null; undefined;object(new Object();)
if(temp){
    console.log("yuan")
}else {
    console.log("alex")
}
// 不论temp值是多少,只根据false和true判断走哪个分支语句

let x = null;
let y = "default";
console.log(x ?? y); // "default"

let z = 0;
console.log(z ?? y); // 0,因为0不是null或undefined

let user = { name: "John", address: { city: "New York" } };
console.log(user?.address?.city); // "New York"
console.log(user?.profile?.age);  // undefined,因为profile不存在

 2.10 控制语句

(1)if条件控制语句 

格式类似c语言的if:
if (表达式1){
    语句块1;
}else if (表达式2){
    语句块2;
}else{
    语句块3;
}   // 表达式的值为true则执行相应的{}里的语句块,if 可以单独使用

var x= (new Date()).getDay();
//获取今天的星期值,0为星期天
var y;

if ( (x==6) || (x==0) ) {
y="周末";
}else{
y="工作日";
}

alert(y);

//等价于

y="工作日";
if ( (x==6) || (x==0) ) {
y="周末";
}
(2)switch选择控制语句

格式如下:(类似c语言中的switch语句,python中没有switch语句)
switch (表达式) {
    case 值1:语句1;break;
    case 值2:语句2;break;
    case 值3:语句3;break;
    default:语句4;
}  // 因为只判断一个条件,执行一个表达式,将表达式的值与每个case的值比较,进而选择从哪一个case的语句块开始执行(break跳出),效率比if-else多分支结构更高,同时结构更加简洁清晰,使程序可读性更强,但只能对基本类型进行数值比较,而if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断

 (3)for循环控制语句
  • 格式如下:(类似c语言的for循环语句,与python的for循环不一样)
    for (初始化;条件;增量){
        语句块;
    }
  • 功能说明:实现条件循环,当条件成立时,执行语句块,否则跳出循环体 
  • (初始化;条件;增量) 也可以写成(var i in arr),arr是数组,i得到的是索引下标,但这种方式渲染html时有bug,不推荐使用:循环的是你获取的一个DOM元素集,for in用来循环对象的所有属性,dom元素集包含了你上面输出的属性。
for (var i=1;i<=7;i++){
    document.write("<H"+i+">hello</H "+i+"> ");
    document.write("<br>");
}
----------------------------------------------
var arr=[1,"hello",true]//var dic={"1":"111"}
for (var i in arr){
    console.log(i)
    console.log(arr[i])
}
----------------------------------------------
doms=document.getElementsByTagName("p");

for (var i in doms){
    console.log(i); // 0 1 2 length item namedItem
    //console.log(doms[i])
}

//循环的是你获取的一个DOM元素集,for in用来循环对象的所有属性,dom元素集包含了你上面输出的属性。
//如果你只要循环dom对象的话,可以用for循环:

for (var i=0;i<doms.length;i++){
    console.log(i) ; // 0 1 2
    //console.log(doms[i])
    }
(4)while循环控制语句 

格式如下:
while (条件){
语句1;
...
}  // 功能说明:运行功能和for类似,当条件成立循环执行语句花括号{}内的语句,否则跳出循环 

2.11 异常处理 

  • 格式如下:
    try {
        //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
    }
    catch (e) {
        // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
        //e是一个局部变量,用来指向Error对象或者其他抛出的对象
    }
    finally {
         //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。
    }
  • 注:主动抛出异常 throw Error('xxxx') 

2.12 ECMAScript类

  • 从ECMAScript 2015(也称为ES6)开始,ECMAScript引入了类的概念。类是通过 class 关键字来定义的,并且支持继承。这是JavaScript语言的一个重要更新,使得面向对象编程更加直观和方便。
  • 现代浏览器如Chrome、Firefox、Safari和Edge都已经广泛支持ES6的新特性。IE7到IE11等旧版浏览器则基本不支持ES6。要查看浏览器对ES6特性的具体支持情况,可以参考兼容性表,如Kangax的ECMAScript 6 Compatibility Table。

  • 此外,Node.js也逐步增加了对ES6特性的支持,从较新的版本开始,许多ES6特性已经可以在Node.js环境中直接使用。

  • 对于不支持ES6的环境,开发者可以使用Babel等转译工具将ES6代码转换为向后兼容的JavaScript代码。

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

let dog = new Dog('Buddy');
dog.speak(); // 输出: Buddy barks.

/*例子中,定义了一个基类 Animal 和一个继承自 Animal 的子类 Dog。
每个类都有一个构造函数(constructor),用于初始化对象的状态。
Dog 类中还重写了Animal的speak 方法,以提供特定于狗的行为。

ECMAScript的类是基于原型的,这意味着它们实际上是函数的语法糖。
每个类都有一个与之关联的原型对象,该对象包含类的所有方法。
当你创建类的实例时,该实例实际上是从类的原型对象上继承而来的。

尽管ECMAScript的类提供了类似于传统面向对象编程语言的语法和特性,
但它们仍然是基于JavaScript的原型继承机制实现的。
这意味着你可以使用所有与原型相关的特性和操作
(如 Object.create() 和 instanceof 运算符)与类一起工作。*/
(1)定义类
  • 使用class关键字(ES6引入)定义类,作为面向对象编程(OOP)在JavaScript中的一个更直观和易于理解的实现 
  • 构造函数(Constructor)‌:
    • 一个特殊的方法,用于在创建类的实例时初始化对象的属性,类似python类的__init__方法。
    • 构造函数使用 constructor 关键字定义,并且会在你使用 new 关键字创建类的实例时自动调用。
  • 属性(Properties)‌:
    • 类的属性通常是在构造函数中定义的;
    • 也可以在类体内部直接定义;
    • 属性可以是任何JavaScript数据类型,包括原始值、对象、数组、函数等。
  • 方法(Methods)‌:
    • 在类体内部定义的函数;
    • 可以访问和修改类的属性,并提供类的行为。
  • 静态方法(Static Methods)‌:
    • 静态方法是属于类本身的,而不是属于类的实例的;
    • 它们使用 static 关键字定义;
    • 可以通过类名直接调用,而不是通过类的实例。
  • getter 和 setter‌:
    • 控制对类属性的访问和修改。
    • getter 方法让你能够定义一个方法来获取一个属性的值;
    • setter 方法让你能够定义一个方法来设置一个属性的值。
  • 计算属性名(Computed Property Names)‌:在类体内部,可以使用计算属性名来动态地定义属性。
class Person {
  // 构造函数
  constructor(name, age) {
    this.name = name; // 定义name属性
    this.age = age;   // 定义age属性
  }

  // 方法
  sayHello() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }

  // 静态方法
  static greet() {
    console.log("Hello from the Person class!");
  }

  // getter
  get ageInDogYears() {
    return this.age * 7;
  }

  // setter
  set age(newAge) {
    if (newAge > 0) {
      this._age = newAge; // 通常,我们会在内部使用一个不同的属性名来存储实际的值
    } else {
      console.log("Age must be positive!");
    }
  }

  // 计算属性名(这里只是作为示例,通常不会在构造函数之外使用)
  ‌:ml-search[`ageIn${this.unit}`] {
    return this.age * (this.unit === 'dogYears' ? 7 : 1);
  }
}

// 创建类的实例
let john = new Person("John", 30);

// 调用实例的方法
john.sayHello(); // 输出: Hello, my name is John and I am 30 years old.

// 访问getter
console.log(john.ageInDogYears); // 输出: 210

// 调用静态方法
Person.greet(); // 输出: Hello from the Person class!

// 使用setter设置属性
john.age = 31;
console.log(john.age); // 输出: 31 (注意:这里的输出是基于我们假设setter正确设置了_age属性)

// 尝试设置一个无效的年龄
john.age = -5; // 输出: Age must be positive!

/*例子中,Person 类有一个构造函数,
它接受 name 和 age 参数,并将它们分别赋值给实例的 name 和 age 属性。
类还有一个 sayHello 方法,用于输出一个问候语。
greet 是一个静态方法,它可以直接通过类名调用。
ageInDogYears 是一个 getter,它计算并返回人的年龄相当于狗的年龄(假设狗的年龄是人的年龄的7倍)。
age 的 setter 方法允许我们设置人的年龄,但会检查年龄是否为正数。
最后展示了如何使用计算属性名来定义一个动态的方法,
尽管在这个特定的例子中,它并不是很有用。*/
(2)实例化
// 创建类的实例
let john = new Person("John", 30);

2.13 ECMAScript对象 

  • ES6之前ECMAScript 并不真正具有类,ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。 
  • 对象(Object)是一种无序的集合,由键值对(key-value pairs)组成,用于存储和组织数据。
  • 键(key)通常是字符串,但也可以是符号(Symbol),而值(value)则可以是任何JavaScript数据类型,包括原始值(如数字、字符串、布尔值)、对象、数组、函数等。
  • 由ECMAScript定义的本地对象.独立于宿主环境的 ECMAScript 实现提供的对象.(native object)
  • ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现.这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。(built-in object)
  • 所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。
     
(1)创建对象 
  • ES6之前,传统的创建对象的方法查看上面2.4(5)节
  • ES6引入了类(class)语法,通过类实例化得到对象,提供了更清晰的面向对象编程风格
(2)访问和设置属性‌ 
  • 使用点符号:objectName.propertyName
  • 使用方括号语法:objectName["propertyName"],这在属性名是一个变量或包含特殊字符时特别有用。
(3)删除属性 

使用delete操作符,如:delete objectName.propertyName

(4)遍历对象 
  • 使用for...in循环来遍历对象原型链上的所有可枚举属性。
  • 使用Object.keys(obj)来获取对象自身的所有可枚举属性名,并使用循环来遍历它们。
  • 使用Object.values(obj) 返回一个包含给定对象自身所有可枚举属性值的数组。
  • 使用Object.entries(obj)来获取对象自身的所有可枚举属性的键值对数组,并使用循环来遍历它们。
    const obj = { name: 'Alice', age: 25, city: 'New York' };
    
    const keys = Object.keys(obj);
    console.log(keys); // 输出: ['name', 'age', 'city']
    
    const values = Object.values(obj);
    console.log(values); // 输出: ['Alice', 25, 'New York']
    
    const entries = Object.entries(obj);
    console.log(entries); // 输出: [['name', 'Alice'], ['age', 25], ['city', 'New York']]
    
    entries.forEach(([key, value]) => {
      console.log(`${key}: ${value}`);
    });
    // 输出:
    // name: Alice
    // age: 25
    // city: New York

(5)对象方法 

对象可以包含方法(即作为对象属性的函数),这些方法可以访问和修改对象的属性 

(6)this关键字 

在对象的方法内部,this关键字引用该方法所属的对象 

(7)对象的内置方法 

JavaScript提供了一些内置的对象方法,如Object.create()Object.defineProperty()Object.freeze()等,用于创建对象、定义属性、冻结对象等 

(8)示例 
// 创建一个对象
let person = {
  name: "John",
  age: 30,
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

// 访问对象的属性
console.log(person.name); // 输出 "John"
console.log(person["age"]); // 输出 30

// 调用对象的方法
person.greet(); // 输出 "Hello, my name is John"

// 设置对象的属性
person.age = 31;
console.log(person.age); // 输出 31

// 删除对象的属性
delete person.age;
console.log(person.age); // 输出 undefined,因为属性已经被删除

// 遍历对象的属性
for (let key in person) {
  console.log(key + ": " + person[key]);
}
// 输出:
// name: John
// greet: function () { ... }
/*
例子中,创建了一个名为person的对象,它包含name和age属性以及一个greet方法。
我们演示了如何访问和设置对象的属性,如何调用对象的方法,以及如何删除对象的属性。
最后,我们还展示了如何使用for...in循环来遍历对象的属性*/
 (9)高级用法

涵盖了多种技术和模式,更有效地利用对象的特性,提升代码的可读性、可维护性和重用性,常见高级用法如下:

  1. 对象字面量增强‌:

    • 在ES6及更高版本中,对象字面量得到了增强,支持属性名的简写、方法的简写以及计算属性名。
    • 例如,你可以直接在对象字面量中定义方法,而无需使用function关键字。
  2. 对象解构‌:

    • 解构赋值允许你从数组或对象中提取数据,并将其赋值给变量。
    • 对于对象,你可以使用花括号{}来解构,并指定要提取的属性名。
    • 你还可以使用默认值来处理不存在的属性。
  3. 对象的扩展运算符‌:

    • 扩展运算符...可以用于对象,以复制对象的属性到另一个对象中。
    • 这在合并对象、创建对象副本或向对象添加新属性时非常有用。
  4. 对象的保护‌:

    • Object.freeze()方法可以冻结一个对象,阻止修改其现有属性,阻止添加新属性,以及阻止删除已有属性。(数据属性变为不可写,访问器属性变为不可配置)
    • 冻结的对象在浅比较时是相等的,因为它们的内容不会改变。
    • Object.seal() 方法可以封闭一个对象,防止新属性的添加,但允许修改现有属性的值。
  5. 代理(Proxy)和反射(Reflect)‌:

    • 代理允许你创建一个对象的代理来定义其基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
    • 反射是一个内置的对象,它提供拦截JavaScript底层操作的方法。
    • 代理和反射通常一起使用,以实现高级的功能,如数据绑定、数据验证等。
  6. 对象的封装和私有字段‌:

    • 在类(class)中,你可以使用私有字段(在字段名前加#)来封装数据,使其只能在类的内部访问。
    • 这有助于隐藏实现细节,并提供一个更清晰的公共API。
  7. 混合(Mixins)‌:

    • 混合是一种将多个对象的行为合并到一个对象中的技术。
    • 它允许你重用代码,通过组合而不是继承来实现对象的多样化行为。
  8. 对象的迭代器‌:</

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

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

相关文章

基于SpringBoot的青年公寓服务平台的设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

使用LLaMA-Factory对AI进行认知的微调

使用LLaMA-Factory对AI进行认知的微调 引言1. 安装LLaMA-Factory1.1. 克隆仓库1.2. 创建虚拟环境1.3. 安装LLaMA-Factory1.4. 验证 2. 准备数据2.1. 创建数据集2.2. 更新数据集信息 3. 启动LLaMA-Factory4. 进行微调4.1. 设置模型4.2. 预览数据集4.3. 设置学习率等参数4.4. 预览…

在无sudo权限Linux上安装 Ollama 并使用 DeepSeek-R1 模型

本教程将指导你如何在 Linux 系统上安装 Ollama&#xff08;一个本地运行大型语言模型的工具&#xff09;&#xff0c;并加载 DeepSeek-R1 模型。DeepSeek-R1 是一个高性能的开源语言模型&#xff0c;适用于多种自然语言处理任务。 DeepSeek-R1 简介 DeepSeek-R1 是 DeepSeek …

蓝桥杯思维训练营(一)

文章目录 题目总览题目详解翻之一起做很甜的梦 蓝桥杯的前几题用到的算法较少&#xff0c;大部分考察的都是思维能力&#xff0c;方法比较巧妙&#xff0c;所以我们要积累对应的题目&#xff0c;多训练 题目总览 翻之 一起做很甜的梦 题目详解 翻之 思维分析&#xff1a;一开…

纯后训练做出benchmark超过DeepseekV3的模型?

论文地址 https://arxiv.org/pdf/2411.15124 模型是AI2的&#xff0c;他们家也是玩开源的 先看benchmark&#xff0c;几乎是纯用llama3 405B后训练去硬刚出一个gpt4o等级的LLamA405 我们先看之前的机遇Lllama3.1 405B进行全量微调的模型 Hermes 3&#xff0c;看着还没缘模型…

OpenAI深夜反击:o3-mini免费上线,能否撼动DeepSeek的地位?

还在为寻找合适的 AI 模型而烦恼吗&#xff1f;chatTools 平台为您精选 o1、GPT4o、Claude、Gemini 等顶尖 AI 模型&#xff0c;满足您不同的 AI 应用需求。立即体验强大的 AI 能力&#xff01; 深夜反击&#xff0c;OpenAI祭出o3-mini 在DeepSeek异军突起&#xff0c;搅动AI行…

【Linux-网络】初识计算机网络 Socket套接字 TCP/UDP协议(包含Socket编程实战)

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;一、初识计算机网络 &#x1f4d6; 背景 &#x1f4d6; 网络协议 &#x1f516;OSI七层…

使用ollama在本地部署一个deepseek大模型

文章目录 为什么选择本地化部署需要用到什么作者使用的什么环境如何根据自己的电脑或服务器配置选择自己能部署的大模型 一、Ollama1、下载Ollama2、安装Ollama 二、DeepSeek R11、下载DeepSeek R12、安装DeepSeek R1 三、ChatBox AI1、下载ChatBox AI2、安装ChatBox AI3、连接…

10 Flink CDC

10 Flink CDC 1. CDC是什么2. CDC 的种类3. 传统CDC与Flink CDC对比4. Flink-CDC 案例5. Flink SQL 方式的案例 1. CDC是什么 CDC 是 Change Data Capture&#xff08;变更数据获取&#xff09;的简称。核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数…

【含文档+PPT+源码】基于微信小程序连锁药店商城

项目介绍 本课程演示的是一款基于微信小程序连锁药店商城&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该项目附带的…

[免费]微信小程序智能商城系统(uniapp+Springboot后端+vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序智能商城系统(uniappSpringboot后端vue管理端)&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序智能商城系统(uniappSpringboot后端vue管理端) Java毕业设计_哔哩哔哩_bilibili 项目介绍…

2025年02月02日Github流行趋势

项目名称&#xff1a;oumi 项目地址url&#xff1a;https://github.com/oumi-ai/oumi 项目语言&#xff1a;Python 历史star数&#xff1a;1416 今日star数&#xff1a;205 项目维护者&#xff1a;xrdaukar, oelachqar, taenin, wizeng23, kaisopos 项目简介&#xff1a;构建最…

vue入门到实战 三

目录 3.1 v-bind 3.1.1 v-bind指令用法 ​编辑3.1.2 使用v-bind绑定class 3.1.3 使用v-bind绑定style 3.2.1 v-if指令 3.2.1 v-if指令 3.2.2 v-show指令 ​3.3 列表渲染指令v-for 3.3.1 基本用法 3.3.2 数组更新 3.3.3 过滤与排序 3.4 事件处理 3.4.1 使用v-on指令…

实验六 项目二 简易信号发生器的设计与实现 (HEU)

声明&#xff1a;代码部分使用了AI工具 实验六 综合考核 Quartus 18.0 FPGA 5CSXFC6D6F31C6N 1. 实验项目 要求利用硬件描述语言Verilog&#xff08;或VHDL&#xff09;、图形描述方式、IP核&#xff0c;结合数字系统设计方法&#xff0c;在Quartus开发环境下&#xff…

java SSM框架 商城系统源码(含数据库脚本)

商城购物功能&#xff0c;项目代码&#xff0c;mysql脚本&#xff0c;html等静态资源在压缩包里面 注册界面 登陆界面 商城首页 文件列表 shop/.classpath , 1768 shop/.project , 1440 shop/.settings/.jsdtscope , 639 shop/.settings/org.eclipse.core.resources.prefs , …

Unet 改进:在encoder和decoder间加入TransformerBlock

目录 1. TransformerBlock 2. Unet 改进 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. TransformerBlock TransformerBlock是Transformer模型架构的基本组件,广泛应用于机器翻译、文本摘要和情感分析等自然语言处理任务…

【Linux系统】信号:认识信号 与 信号的产生

信号快速认识 1、生活角度的信号 异步&#xff1a;你是老师正在上课&#xff0c;突然有个电话过来资料到了&#xff0c;你安排小明过去取资料&#xff0c;然后继续上课&#xff0c;则小明取资料这个过程就是异步的 同步&#xff1a;小明取快递&#xff0c;你停下等待小明回来再…

一、html笔记

(一)前端概述 1、定义 前端是Web应用程序的前台部分,运行在PC端、移动端等浏览器上,展现给用户浏览的网页。通过HTML、CSS、JavaScript等技术实现,是用户能够直接看到和操作的界面部分。上网就是下载html文档,浏览器是一个解释器,运行从服务器下载的html文件,解析html、…

PyQt5超详细教程终篇

PyQt5超详细教程 前言 接&#xff1a; [【Python篇】PyQt5 超详细教程——由入门到精通&#xff08;序篇&#xff09;](【Python篇】PyQt5 超详细教程——由入门到精通&#xff08;序篇&#xff09;-CSDN博客) 建议把代码复制到pycahrm等IDE上面看实际效果&#xff0c;方便理…

洛谷 P8724 [蓝桥杯 2020 省 AB3] 限高杆

洛谷题目传送门 题目描述 某市有 n 个路口&#xff0c;有 m 段道路连接这些路口&#xff0c;组成了该市的公路系统。其中一段道路两端一定连接两个不同的路口。道路中间不会穿过路口。 由于各种原因&#xff0c;在一部分道路的中间设置了一些限高杆&#xff0c;有限高杆的路…