11.与JavaScript深入交流-[js一篇通]

news2024/12/23 3:07:06

文章目录

  • 1.变量的使用
    • 1.1基本用法
    • 1.2理解 动态类型
  • 2.基本数据类型
    • 2.1number 数字类型
      • 2.1.1数字进制表示
      • 2.1.2特殊的数字值
    • 2.2string 字符串类型
      • 2.2.1基本规则
      • 2.2.2转义字符
      • 2.2.3求长度
      • 2.2.4字符串拼接
    • 2.3boolean 布尔类型
    • 2.4undefined 未定义数据类型
    • 2.5null 空值类型
  • 3.运算符
    • 3.1算术运算符
    • 3.2赋值运算符 & 复合赋值运算符
    • 3.3自增自减运算符
    • 3.4比较运算符
    • 3.5逻辑运算符
    • 3.6位运算
    • 3.7移位运算
  • 4.条件语句
    • 4.1if 语句
      • 4.1.1基本语法格式
      • 4.1.2练习案例
    • 4.2三元表达式
    • 4.3switch
  • 5.循环语句
    • 5.1while 循环
    • 5.2continue
    • 5.3break
    • 5.4for 循环
  • 6.数组
    • 6.1创建数组
    • 6.2获取数组元素
    • 6.3新增数组元素
      • 6.3.1通过修改 length 新增
      • 6.3.2通过下标新增
      • 6.3.3使用 push 进行追加元素
      • 6.3.4数组的三种循环遍历
    • 6.4删除数组中的元素
  • 7.函数
    • 7.1语法格式
    • 7.2关于参数个数
    • 7.3函数表达式
    • 7.4作用域
    • 7.5作用域链
  • 8.对象
    • 8.1基本概念
      • 8.1.1使用 字面量 创建对象 [常用]
      • 8.1.2使用 new Object 创建对象
      • 8.1.3使用 构造函数 创建对象
    • 8.2理解 new 关键字
    • 8.3JavaScript 的对象和 Java 的对象的区别
      • 8.3.1JavaScript 没有 "类" 的概念
      • 8.3.2JavaScript 对象不区分 "属性" 和 "方法"
      • 8.3.3JavaScript 对象没有 private / public 等访问控制机制.
      • 8.3.4JavaScript 对象没有 "继承"
      • 8.3.5JavaScript 没有 "多态"
      • 8.3.3JavaScript 对象没有 private / public 等访问控制机制.
      • 8.3.4JavaScript 对象没有 "继承"
      • 8.3.5JavaScript 没有 "多态"

大家好,我是晓星航。今天为大家带来的是 JavaScript语法描述 相关的讲解!😀

1.变量的使用

1.1基本用法

创建变量(变量定义/变量声明/变量初始化)

var name = 'zhangsan';
var age = 20;

var 是 JS 中的关键字, 表示这是一个变量.

= 在 JS 中表示 “赋值”, 相当于把数据放到内存的盒子中. = 两侧建议有一个空格

每个语句最后带有一个 ; 结尾. JS 中可以省略 ; 但是建议还是加上.

注意, 此处的 ; 为英文分号. JS 中所有的标点都是英文标点.

初始化的值如果是字符串, 那么就要使用单引号或者双引号引起来.

初始化的值如果是数字, 那么直接赋值即可.

使用变量

console.log(age); // 读取变量内容
age = 30;         // 修改变量内容

为啥动漫中的角色都是要先喊出技能名字再真正释放技能?

就是因为变量要先声明才能使用.

代码示例: 弹框提示用户输入信息, 再弹框显示.

var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name);
alert("您的年龄是: " + age);
alert("您的分数是: " + score);

也可以把三个输出内容合并成一次弹框

var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name + "\n" + "您的年龄是: " + age + "\n" + "您的分数是: " +
score + "\n");
  • + 表示字符串拼接, 也就是把两个字符串首尾相接变成一个字符串.
  • \n 表示换行

JavaScript 中还支持使用 let 定义变量. 用法和 var 基本类似. 用法上的差异此处暂时不讨论.

1.2理解 动态类型

  1. JS 的变量类型是程序运行过程中才确定的(运行到 = 语句才会确定类型)
var a = 10;     // 数字
var b = "hehe"; // 字符串
  1. 随着程序运行, 变量的类型可能会发生改变.
var a = 10;    // 数字
a = "hehe";    // 字符串

这一点和 C Java 这种静态类型语言差异较大.

C, C++, Java, Go 等语言是静态类型语言. 一个变量在创建的时候类型就确定了, 不能在运行时发生改变.

而 JS,python,PHP,Lua…都是动态类型,一个变量在创建的时候类型就是可以随便变化的,在运行时不能确定具体类型,但是可以发生改变类型的操作

如果尝试改变, 就会直接编译报错.

动态类型和静态类型适用的范围:

动态类型的语言特别适合初创型公司,规模小,特别赶时间。

而静态类型适合规模大,业务更稳定的公司,因为这类公司大部分时间都在做维护工作,而动态类型由于具体类型不能确定,此时维护的成本就很高(程序猿维护时因为不清楚具体类型在了解类型时会消耗更多的时间成本)

例如:字节,b站,豆瓣,知乎…这些大公司一开始也是使用 JS 来开发大型项目的(因为以前前端页面只有JS,而JS是动态类型没得选),后来 TS 火了之后,这些大厂纷纷都切换到了 TS 了。(因为TS功能更强大,且是静态类型便于后期的软件维护)

2.基本数据类型

JS 中内置的几种类型

  • number: 数字. 不区分整数和小数.
  • boolean: true 真, false 假.
  • string: 字符串类型.
  • undefined: 只有唯一的值 undefined. 表示未定义的值.
  • null: 只有唯一的值 null. 表示空值.

2.1number 数字类型

JS 中不区分整数和浮点数, 统一都使用 “数字类型” 来表示.

2.1.1数字进制表示

计算机中都是使用二进制来表示数据, 而人平时都是使用十进制.

因为二进制在使用过程中不太方便(01太多会看花眼).

所以在日常使用二进制数字时往往使用 八进制 和 十六进制 来表示二进制数字.

var a = 07;      // 八进制整数, 以 0 开头
var b = 0xa;     // 十六进制整数, 以 0x 开头
var c = 0b10;    // 二进制整数, 以 0b 开头

注意:

  • 一个八进制数字对应三个二进制数字
  • 一个十六进制数字对应四个二进制数字. (两个十六进制数字就是一个字节)

各种进制之间的转换, 不需要手工计算, 直接使用计算器即可.

2.1.2特殊的数字值

Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.

-Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.

NaN: 表示当前的结果不是一个数字.

var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);

注意:

  1. 负无穷大 和 无穷小 不是一回事. 无穷小指无限趋近与 0, 值为 1 / Infinity
  2. ‘hehe’ + 10 得到的不是 NaN, 而是 ‘hehe10’, 会把数字隐式转成字符串, 再进行字符串拼接.
  3. 可以使用 isNaN 函数判定是不是一个非数字.
console.log(isNaN(10));  // false
console.log(isNaN('hehe' - 10));  // true

2.2string 字符串类型

2.2.1基本规则

字符串字面值需要使用引号引起来, 单引号双引号均可.

var a = "haha";
var b = 'hehe';
var c = hehe;    // 运行出错

如果字符串中本来已经包含引号咋办?

var msg = "My name is "zhangsan"";    // 出错
var msg = "My name is \"zhangsan\"";  // 正确, 使用转义字符. \" 来表示字符串内部的引号. 
var msg = "My name is 'zhangsan'";    // 正确, 搭配使用单双引号
var msg = 'My name is "zhangsan"';    // 正确, 搭配使用单双引号

2.2.2转义字符

有些字符不方便直接输入, 于是要通过一些特殊方式来表示.

  • \n
  • \\
  • \'
  • \"
  • \t

2.2.3求长度

使用 String 的 length 属性即可

var a = 'hehe';
console.log(a.length);

var b = '哈哈';
console.log(b.length);

结果:

4
2

单位为字符的数量

2.2.4字符串拼接

使用 + 进行拼接

var a = "my name is ";
var b = "zhangsan";
console.log(a + b);

注意, 数字和字符串也可以进行拼接

var c = "my score is ";
var d = 100;
console.log(c + d);

注意, 要认准相加的变量到底是字符串还是数字

console.log(100 + 100);     // 200
console.log('100' + 100);   // 100100

2.3boolean 布尔类型

表示 “真” 和 “假”

boolean 原本是数学中的概念 (布尔代数).

在计算机中 boolean 意义重大, 往往要搭配条件/循环完成逻辑判断.

Boolean 参与运算时当做 1 和 0 来看待.

console.log(true + 1);
console.log(false + 1)

这样的操作其实是不科学的. 实际开发中不应该这么写.

2.4undefined 未定义数据类型

如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型

var a;
console.log(a)

undefined 和字符串进行相加, 结果进行字符串拼接

console.log(a + "10");  // undefined10

undefined 和数字进行相加, 结果为 NaN

console.log(a + 10);

2.5null 空值类型

null 表示当前的变量是一个 “空值”.

var b = null;
console.log(b + 10);    // 10
console.log(b + "10");  // null10

注意:

null 和 undefined 都表示取值非法的情况, 但是侧重点不同.

null 表示当前的值为空. (相当于有一个空的盒子)

undefined 表示当前的变量未定义. (相当于连盒子都没有)

3.运算符

JavaScript 中的运算符和 Java 用法基本相同. 此处不做详细介绍了.

3.1算术运算符

  • +
  • /
  • %

3.2赋值运算符 & 复合赋值运算符

  • =
  • +=
  • -=
  • *=
  • /=
  • %=

3.3自增自减运算符

  • ++: 自增1
  • –: 自减1

3.4比较运算符

  • <
  • >
  • <=
  • >=
  • == 比较相等(会进行隐式类型转换)
  • !=
  • === 比较相等(不会进行隐式类型转换)
  • !==

3.5逻辑运算符

用于计算多个 boolean 表达式的值.

  • && 与: 一假则假
  • || 或: 一真则真
  • ! 非

3.6位运算

  • & 按位与
  • | 按位或
  • ~ 按位取反
  • ^ 按位异或

3.7移位运算

  • << 左移
  • >> 有符号右移(算术右移)
  • >>> 无符号右移(逻辑右移)

4.条件语句

4.1if 语句

4.1.1基本语法格式

条件表达式为 true, 则执行 if 的 { } 中的代码

// 形式1
if (条件) {
    语句
}
// 形式2
if (条件) {
    语句1
} else {
    语句2
}
// 形式3
if (条件1) {
    语句1
} else if (条件2) {
    语句2   
} else if .... {
    语句...
} else {
    语句N
}

4.1.2练习案例

代码示例1: 判定一个数字是奇数还是偶数

var num = 10;
if (num % 2 == 0) {
    console.log("num 是偶数");
} else {
    console.log("num 是奇数");
}

注意! 不能写成 num % 2 == 1 就是奇数. 负的奇数 % 2 结果可能是 -1.

代码示例2: 判定一个数字是正数还是负数

var num = 10;
if (num > 0) {
    console.log("num 是正数");
} else if (num < 0) {
    console.log("num 是负数");
} else {
    console.log("num 是 0");
}

代码示例3: 判定某一年份是否是闰年

var year = 2000;
if (year % 100 == 0) {
    // 判定世纪闰年
    if (year % 400 == 0) {
        console.log("是闰年");
   } else {
        console.log("不是闰年");
   }
} else {
    // 普通闰年
    if (year % 4 == 0) {
        console.log("是闰年");
   } else {
        console.log("不是闰年");
   }
}

4.2三元表达式

是 if else 的简化写法.

条件 ? 表达式1 : 表达式2

条件为真, 返回表达式1 的值. 条件为假, 返回表达式2 的值.

注意, 三元表达式的优先级是比较低的.

4.3switch

更适合多分支的场景.

switch (表达式) {
    case1:
        语句1;
        break;
    case2:
        语句2:
        break;
    default:
        语句N;
}

用户输入一个整数, 提示今天是星期几

var day = prompt("请输入今天星期几: ");
switch (parseInt(day)) {
    case 1:
        console.log("星期一");
        break;
    case 2:
        console.log("星期二");
        break;
    case 3:
        console.log("星期三");
        break;
    case 4:
        console.log("星期四");
        break;
    case 5:
        console.log("星期五");
        break;
    case 6:
        console.log("星期六");
        break;
    case 7:
        console.log("星期日");
        break;
    default:
        console.log("输入有误");
}

5.循环语句

重复执行某些语句

5.1while 循环

while (条件) {
    循环体;
}

执行过程:

  • 先执行条件语句
  • 条件为 true, 执行循环体代码.
  • 条件为 false, 直接结束循环

代码示例1: 打印 1 - 10

var num = 1;
while (num <= 10) {
    console.log(num);
    num++;
}

代码示例2: 计算 5 的阶乘

var result = 1;
var i = 1;
while (i <= 5) {
    result *= i;
    i++;
}
console.log(result)

5.2continue

可以跳过本次循环剩余代码,执行下一次循环。

吃五个李子, 发现第三个李子里有一只虫子, 于是扔掉这个, 继续吃下一个李子.

var i = 1;
while (i <= 5) {
    if (i == 3) {
        i++;
        continue;
   }
    console.log("我在吃第" + i + "个李子");
    i++;
}
我在吃第1个李子
我在吃第2个李子
我在吃第4个李子
我在吃第5个李子

代码示例: 找到 100 - 200 中所有 3 的倍数

var num = 100;
while (num <= 200) {
    if (num % 3 != 0) {
        num++;  // 这里的 ++ 不要忘记! 否则会死循环. 
        continue;
   }
    console.log("找到了 3 的倍数, 为:" + num);
    num++;
}

5.3break

结束整个循环

吃五个李子, 发现第三个李子里有半个虫子, 于是剩下的也不吃了.

var i = 1;
while (i <= 5) {
    if (i == 3) {
        break;
   }
    console.log("我在吃第" + i + "个李子");
    i++;
}
我在吃第1个李子
我在吃第2个李子

代码示例: 找到 100 - 200 中第一个 3 的倍数

var num = 100;
while (num <= 200) {
    if (num % 3 == 0) {
        console.log("找到了 3 的倍数, 为:" + num);
        break;
   }
    num++;
}
// 执行结果
找到了 3 的倍数, :102

5.4for 循环

for (表达式1; 表达式2; 表达式3) {
 循环体
}
  • 表达式1: 用于初始化循环变量.
  • 表达式2: 循环条件
  • 表达式3: 更新循环变量.

执行过程:

  • 先执行表达式1, 初始化循环变量
  • 再执行表达式2, 判定循环条件
  • 如果条件为 false, 结束循环
  • 如果条件为 true, 则执行循环体代码.
  • 执行表达式3 更新循环变量

代码示例1: 打印 1 - 10 的数字

for (var num = 1; num <= 10; num++) {
    console.log(num);
}

代码示例2: 计算 5 的阶乘

var result = 0;
for (var i = 1; i <= 5; i++) {
    result *= i;
}
console.log("result = " + result);

6.数组

6.1创建数组

使用 new 关键字创建

// Array 的 A 要大写
var arr = new Array();

使用字面量方式创建 [常用]

var arr = [];
var arr2 = [1, 2, 'haha', false]; // 数组中保存的内容称为 "元素"

注意: JS 的数组不要求元素是相同类型.

这一点和 C, C++, Java 等静态类型的语言差别很大. 但是 Python, PHP 等动态类型语言也是如此.

6.2获取数组元素

使用下标的方式访问数组元素(从 0 开始)

var arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
arr[2] = '小猫凯迪';
console.log(arr);

image-20231017203233304

如果下标超出范围读取元素, 则结果为 undefined

console.log(arr[3]);   // undefined
console.log(arr[-1]);  // undefined

虽然数组越界了,但是代码还是正常运行,没有说报错崩溃。

image-20231017203241342

注意: 不要给数组名直接赋值, 此时数组中的所有元素都没了.

arr[100] = '小狗黄能';
console.log(arr);

这里我们看到,虽然直接打印arr[3]越界了,但是我们设置 arr[100]='小狗黄能'; 之后,我们的数组长度变为了100。

image-20231017203252860

arr['hello']='廉小猫';
console.log(arr);

这里我们的代码为什么可以用字符来当数组下标???

注意我们这里的字符不是单纯的字符了,而是键值对,不如理解成 数组 + Map 的混血儿。

image-20231017203300442

相当于本来 arr 是一个数组, 重新赋值后变成字符串了.

var arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
arr = '小猫凯迪';

6.3新增数组元素

6.3.1通过修改 length 新增

相当于在末尾新增元素. 新增的元素默认值为 undefined

var arr = [9, 5, 2, 7];
arr.length = 6;
console.log(arr);
console.log(arr[4], arr[5]);

image-20231017203307531

6.3.2通过下标新增

如果下标超出范围赋值元素, 则会给指定位置插入新元素

var arr = [];
arr[2] = 10;
console.log(arr)

此时这个数组的 [0] 和 [1] 都是 undefined

6.3.3使用 push 进行追加元素

代码示例一: 给定一个数组, 把数组中的奇数放到一个 newArr 中.

var arr = [9, 5, 2, 7, 3, 6, 8];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
    if (arr[i] % 2 != 0) {
        newArr.push(arr[i]);
   }
}
console.log(newArr);

代码示例二:

var arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
arr.push('小狗黄能');
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

image-20231017203317268

6.3.4数组的三种循环遍历

image-20231017203326068

6.4删除数组中的元素

使用 splice 方法删除元素

var arr = [9, 5, 2, 7];
// 第一个参数表示从下表为 2 的位置开始删除. 第二个参数表示要删除的元素个数是 1 个
arr.splice(2, 1);
console.log(arr);
// 结果
[9, 5, 7]

image-20231017203335696

目前咱们已经用到了数组中的一些属性和方法.

arr.length, length 使用的时候不带括号, 此时 length 就是一个普通的变量(称为成员变量, 也叫属 性)

arr.push(), arr.splice() 使用的时候带括号, 并且可以传参数, 此时是一个函数 (也叫做方法)

image-20231017203342149

7.函数

7.1语法格式

// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
    函数体
    return 返回值;
}
// 函数调用
函数名(实参列表)           // 不考虑返回值
返回值 = 函数名(实参列表)   // 考虑返回值
  • 函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次.
function hello() {
    console.log("hello");
}
// 如果不调用函数, 则没有执行打印语句
hello();
  • 调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
  • 函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)
// 调用函数
hello();
// 定义函数
function hello() {
    console.log("hello");
}

image-20231017203350190

7.2关于参数个数

实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配

  1. 如果实参个数比形参个数多, 则多出的参数不参与函数运算
sum(10, 20, 30);    // 30
  1. 如果实参个数比形参个数少, 则此时多出来的形参值为
sum(10);    // NaN, 相当于 num2 为 undefined. 

NaN:意为not a number (不是一个数字)

undefined JS 的函数传参比较灵活, 这一点和其他语言差别较大. 事实上这种灵活性往往不是好事.

7.3函数表达式

另外一种函数的定义方式

var add = function() {
 var sum = 0;
    for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
   }
    return sum;
}
console.log(add(10, 20));            // 30
console.log(add(1, 2, 3, 4));        // 10
console.log(typeof add);             // function

此时形如 function() { } 这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示. 后面就可以通过这个 add 变量来调用函数了.

JS 中函数是一等公民, 可以用变量保存, 也可以作为其他函数的参数或者返回值.

7.4作用域

某个标识符名字在代码中的有效范围.

在 ES6 标准之前, 作用域主要分成两个

  • 全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
  • 局部作用域/函数作用域: 在函数内部生效.
// 全局变量
var num = 10;
console.log(num);
function test() {
    // 局部变量
      var num = 20;
    console.log(num);
}
function test2() {
    // 局部变量
    var num = 30;
    console.log(num);
}
test();
test2();
console.log(num);
// 执行结果
10
20
30
10

创建变量时如果不写 var, 则得到一个全局变量.

function test() {
 num = 100;
}
test();
console.log(num);
// 执行结果
100

另外, 很多语言的局部变量作用域是按照代码块(大括号)来划分的, JS 在 ES6 之前不是这样的.

if (1 < 2) {
 var a = 10;
}
console.log(a);

image-20231017203359923

这两个代码区别就是 第1个代码:一个是返回到另一个函数继续执行,而 第2个代码:另一个是直接返回另一个函数的结果。

js 中变量的作用域,当代码中访问某个变量的时候,要去哪里找这个变量,js 会先找当前作用域,如果当前作用域没有,就往上层作用域找,一直往上直到全局作用域。如果还找不到,报错/undefined

7.5作用域链

背景:

  • 函数可以定义在函数内部
  • 内层函数可以访问外层函数的局部变量.

内部函数可以访问外部函数的变量. 采取的是链式查找的方式. 从内到外依次进行查找.

var num = 1;
function test1() {
    var num = 10;
    function test2() {
 var num = 20;
        console.log(num);
   }
    test2();
}
test1();
// 执行结果
20

执行 console.log(num) 的时候, 会现在 test2 的局部作用域中查找 num. 如果没找到, 则继续去 test1 中 查找. 如果还没找到, 就去全局作用域查找.

image-20231017203414882

        var num = 1;
        function test1() {
            var num = 2;

            function test2() {
                var num = 3;
                console.log("test2: " + num);
            }
            test2();

            console.log("test1: " + num);
        }
        test1();

        console.log("global: " + num);

image-20231017203426879

8.对象

8.1基本概念

对象是指一个具体的事物.

“电脑” 不是对象, 而是一个泛指的类别. 而 “我的联想笔记本” 就是一个对象.

在 JS 中, 字符串, 数值, 数组, 函数都是对象.

每个对象中包含若干的属性和方法.

  • 属性: 事物的特征.
  • 方法: 事物的行为.

例如, 你有一个女票.

她的身高体重三围这些都是属性.

她的唱歌, 跳舞, 暖床都是方法.

对象需要保存的属性有多个, 虽然数组也能用于保存多个数据, 但是不够好.

例如表示一个学生信息. (姓名蔡徐坤, 身高 175cm, 体重 170斤)

var student = [‘蔡徐坤’, 175, 170];

但是这种情况下到底 175 和 170 谁表示身高, 谁表示体重, 就容易分不清

JavaScript 的对象 和 Java 的对象概念上基本一致. 只是具体的语法表项形式差别较大.

8.1.1使用 字面量 创建对象 [常用]

使用 { } 创建对象

var a = {};  // 创建了一个空的对象
var student = {
    name:'蔡徐坤',
    age: 25,
    height:180,
    weight:70,
    sing: function() {
        console.log("鸡你太美");
    },
    dance: function() {
        console.log("铁山靠");
    },
    rap: function() {
        console.log("你是我是你的谁?");
    }
};
  • 使用 { } 创建对象
  • 属性和方法使用键值对的形式来组织.
  • 键值对之间使用 , 分割. 最后一个属性后面的 , 可有可无
  • 键和值之间使用 : 分割.
  • 方法的值是一个匿名函数.

使用对象的属性和方法:

// 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
console.log(student.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号
console.log(student['height']);
// 3. 调用方法, 别忘记加上 () 
student.sayHello();

eg:

var student = {
    name:'蔡徐坤',
    age: 25,
    height:180,
    weight:70,
    sing: function() {
        console.log("鸡你太美");
    },
    dance: function() {
        console.log("铁山靠");
    },
    rap: function() {
        console.log("你是我是你的谁?");
    }
};
console.log(student.name);
console.log(student.age);
student.sing();

image-20231017203440454

8.1.2使用 new Object 创建对象

var student = new Object();// 和创建数组类似
student.name = '蔡徐坤';
student.age = 25;
student['weight'] = 120;
student.sing = function(){
    console.log("鸡你太美");
};
console.log(student.name);
console.log(student.age);
console.log(student.weight);
student.sing();

image-20231017203450041

注意, 使用 { } 创建的对象也可以随时使用 student.name = "蔡徐坤"; 这样的方式来新增属性.

8.1.3使用 构造函数 创建对象

前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便 的创建 多个对象.

例如: 创建几个猫咪对象

var mimi = {
    name: "咪咪",
    type: "中华田园喵",
    miao: function () {
        console.log("喵");
   }
};
var xiaohei = {
    name: "小黑",
    type: "波斯喵",
    miao: function () {
        console.log("猫呜");
   }
}
var ciqiu = {
    name: "刺球",
    type: "金渐层",
    miao: function () {
        console.log("咕噜噜");
   }
}

此时写起来就比较麻烦. 使用构造函数可以把相同的属性和方法的创建提取出来, 简化开发过程.

基本语法

function 构造函数名(形参) {
    this.属性 =;
    this.方法 = function...
}
    
var obj = new 构造函数名(实参);

注意:

  • 在构造函数内部使用 this 关键字来表示当前正在构建的对象.
  • 构造函数的函数名首字母一般是大写的.
  • 构造函数的函数名可以是名词.
  • 构造函数不需要 return
  • 创建对象的时候必须使用 new 关键字.

this 相当于 “我”

使用构造函数重新创建猫咪对象

function Cat(name, type, sound) {
    this.name = name;
    this.type = type;
    this.miao = function () {
        console.log(sound); // 别忘了作用域的链式访问规则
   }
}
var mimi = new Cat('咪咪', '中华田园喵', '喵');
var xiaohei = new Cat('小黑', '波斯喵', '猫呜');
var ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
console.log(mimi);
mimi.miao();

8.2理解 new 关键字

new 的执行过程:

  1. 先在内存中创建一个空的对象 { }
  2. this 指向刚才的空对象(将上一步的对象作为 this 的上下文)
  3. 执行构造函数的代码, 给对象创建属性和方法
  4. 返回这个对象 (构造函数本身不需要 return, 由 new 代劳了)

参考:[new运算符解析](new 运算符 - JavaScript | MDN (mozilla.org))

8.3JavaScript 的对象和 Java 的对象的区别

8.3.1JavaScript 没有 “类” 的概念

对象其实就是 “属性” + “方法” .

类相当于把一些具有共性的对象的属性和方法单独提取了出来, 相当于一个 “月饼模子”

在 JavaScript 中的 “构造函数” 也能起到类似的效果.

而且即使不是用构造函数, 也可以随时的通过 { } 的方式指定出一些对象

在 ES6 中也引入了 class 关键字, 就能按照类似于 Java 的方式创建类和对象了.

8.3.2JavaScript 对象不区分 “属性” 和 “方法”

JavaScript 中的函数是 “一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行.

8.3.3JavaScript 对象没有 private / public 等访问控制机制.

对象中的属性都可以被外界随意访问.

8.3.4JavaScript 对象没有 “继承”

继承本质就是 “让两个对象建立关联”. 或者说是让一个对象能够重用另一个对象的属性/方法.

JavaScript 中使用 “原型” 机制实现类似的效果.

例如: 创建一个 cat 对象和 dog 对象, 让这两个对象都能使用 animal 对象中的 eat 方法.

通过 __proto__ 属性来建立这种关联关系 (proto 翻译作 “原型”)

image-20231017203601424

当eat方法被调用的时候,先在自己的方法列表中寻找, 如果找不到,就去找原型中的方法, 如果原型 中找不到, 就去原型的原型中去寻找… 最后找到Object那里, 如果还找不到, 那就是未定义了。

image-20231017203627485

关于原型链的内容比较复杂, 此处不做过多讨论

8.3.5JavaScript 没有 “多态”

多态的本质在于 “程序猿不必关注具体的类型, 就能使用其中的某个方法”.

C++ / Java 等静态类型的语言对于类型的约束和校验比较严格. 因此通过 子类继承父类, 并重写父类的方 法的方式 来实现多态的效果.

但是在 JavaScript 中本身就支持动态类型, 程序猿在使用对象的某个方法的时候本身也不需要对对象的类 型做出明确区分. 因此并不需要在语法层面上支持多态.

例如:

在 Java 中已经学过 ArrayList 和 LinkedList. 为了让程序猿使用方便, 往往写作

List list = new ArrayList<>()

然后我们可以写一个方法:

void add(List<String> list, String s) {
 list.add(s);   
}

我们不必关注 list 是 ArrayList 还是 LinkedList, 只要是 List 就行. 因为 List 内部带有 add 方法.

当我们使用 JavaScript 的代码的时候

function add(list, s) {
 list.add(s)
}

add 对于 list 这个参数的类型本身就没有任何限制. 只需要 list 这个对象有 add 方法即可. 就不必 像 Java 那样先继承再重写绕一个圈子.

“一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行.

8.3.3JavaScript 对象没有 private / public 等访问控制机制.

对象中的属性都可以被外界随意访问.

8.3.4JavaScript 对象没有 “继承”

继承本质就是 “让两个对象建立关联”. 或者说是让一个对象能够重用另一个对象的属性/方法.

JavaScript 中使用 “原型” 机制实现类似的效果.

例如: 创建一个 cat 对象和 dog 对象, 让这两个对象都能使用 animal 对象中的 eat 方法.

通过 __proto__ 属性来建立这种关联关系 (proto 翻译作 “原型”)

[外链图片转存中…(img-ZCVFCBcm-1698739596171)]

当eat方法被调用的时候,先在自己的方法列表中寻找, 如果找不到,就去找原型中的方法, 如果原型 中找不到, 就去原型的原型中去寻找… 最后找到Object那里, 如果还找不到, 那就是未定义了。

[外链图片转存中…(img-miSAhFQg-1698739596171)]

关于原型链的内容比较复杂, 此处不做过多讨论

8.3.5JavaScript 没有 “多态”

多态的本质在于 “程序猿不必关注具体的类型, 就能使用其中的某个方法”.

C++ / Java 等静态类型的语言对于类型的约束和校验比较严格. 因此通过 子类继承父类, 并重写父类的方 法的方式 来实现多态的效果.

但是在 JavaScript 中本身就支持动态类型, 程序猿在使用对象的某个方法的时候本身也不需要对对象的类 型做出明确区分. 因此并不需要在语法层面上支持多态.

例如:

在 Java 中已经学过 ArrayList 和 LinkedList. 为了让程序猿使用方便, 往往写作

List list = new ArrayList<>()

然后我们可以写一个方法:

void add(List<String> list, String s) {
 list.add(s);   
}

我们不必关注 list 是 ArrayList 还是 LinkedList, 只要是 List 就行. 因为 List 内部带有 add 方法.

当我们使用 JavaScript 的代码的时候

function add(list, s) {
 list.add(s)
}

add 对于 list 这个参数的类型本身就没有任何限制. 只需要 list 这个对象有 add 方法即可. 就不必 像 Java 那样先继承再重写绕一个圈子.

感谢各位读者的阅读,本文章有任何错误都可以在评论区发表你们的意见,我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞,你的每一次鼓励都是作者创作的动力哦!😘

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

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

相关文章

半导体制造中的液体污染控制-液体粒子计数器应用

半导体制造是一个高度复杂的过程&#xff0c;包括许多步骤和阶段&#xff0c;每个步骤和阶段都有可能受到污染。在这种情况下&#xff0c;污染可能导致产量昂贵的损失和时间浪费。为了应对这些挑战&#xff0c;实时监控系统提供了一个强大的解决方案&#xff0c;可以立即检测并…

注意!注意!注意!新规|Temu平台强制欧代英代,警惕产品被拒!

注意&#xff01;注意&#xff01;注意&#xff01;新规&#xff5c;Temu平台强制欧代英代&#xff0c;警惕产品被拒&#xff01; 欧代&#xff0c;英代信息怎么办理呢 TEMU平台上有售卖产品必需要求产品打上英代,欧代信息! 10月15日&#xff0c;Temu正式实施欧代&英代新规…

反射率检测仪如何检测后视镜

后视镜反射率检测是评估后视镜质量的重要步骤&#xff0c;可以反映后视镜的反射效果是否满足设计要求。一般来说&#xff0c;后视镜的反射率越高&#xff0c;驾驶员观察车后的道路状况就越清晰&#xff0c;从而能够更好地判断与后方车辆的距离和速度差。 后视镜反射率检测的原理…

Unity 多图片(带透明通道)合成

取个巧&#xff0c;利用Camera和Render Texture 多个2d图片组合成型 每个Square都单独设置一个层级 相机设置 RenderTexture设置&#xff0c;然后将RenderTexture放在一个RawImage上 以下是生成图片的代码 using UnityEngine.UI; using System.Collections; using System.…

Python爬虫程序中的504错误:原因、常见场景和解决方法

概述 在编写Python爬虫程序时&#xff0c;我们经常会遇到各种错误和异常。其中&#xff0c;504错误是一种常见的网络错误&#xff0c;它表示网关超时。是指客户端与服务器之间的网关通信过程中&#xff0c;服务器在规定的时间内没有返回响应&#xff0c;导致请求超时。此类错误…

关于FreeTypeFont‘ object has no attribute ‘getsize‘问题的解决方案

引言 这个问题是在训练yolov5_obb项目遇到的&#xff0c;大概率又是环境问题。如下图&#xff1a; 解决方法 出现这个问题是Pillow版本太高了&#xff0c;下载低版本的&#xff1a; pip install Pillow9.5 OK&#xff01;

解决proteus仿真stm32,IIC通讯,IIC DEBUG无法显示从机应答信号的问题(问题情况为在8位数据后应答位显示?)

1、错误现象 错误现象如下&#xff0c;在IIC数据传输8位数据后&#xff0c;IIC DEBUG的应答位无法显示应答位 2、错误原因 我们打开信号传输的示波器&#xff0c;直接去查看IIC从机校验位的数据波形&#xff0c;可以看到从机示波器显示的的波形为半高ACK&#xff0c;那错误原…

第19期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

【Proteus仿真】【Arduino单片机】简易电子琴

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用无源蜂鸣器、按键等。 主要功能&#xff1a; 系统运行后&#xff0c;按下K1-K7键发出不同音调。 二、软件设计 /* 作者&#xff1a;嗨小易&a…

通讯网关软件031——利用CommGate X2HTTP实现HTTP访问ODBC数据源

本文介绍利用CommGate X2HTTP实现HTTP访问ODBC数据源。CommGate X2HTTP是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现上位机通过HTTP来获取ODBC数据源的数据。 【解决方案】设置网关机…

Jmeter(二十一):jmeter导入和导出接口的处理(超详细)

JMeter测试导入接口 利用Jmeter测试上传文件&#xff0c;首先可根据接口文档或者fiddler抓包分析文件上传的接口&#xff1b;如下图&#xff1a; 以下是我通过fiddler所截取的文件上传的接口 1、填写导入接口的信息 查看文件上传栏下的填写信息&#xff1a; 文件名称&#x…

DM8 Dokcer镜像更新后远程无法jdbc连接问题

背景&#xff1a;原来官网下的dm8docker镜像有效期只有两个星期&#xff0c;问他们商务申请了新的dm8镜像&#xff0c;准备简单升级一下镜像再引入原来的database 先说结论&#xff1a;jdbc驱动要更新 官网dm8驱动链接地址 原来的tag镜像 dm8_single:v8.1.2.128_ent_x86_64…

集简云+管家婆如何无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

网上管家婆专注于为中小企业提供科学经营管理的一站式解决方案。自2009年创办云端SaaS产品&#xff0c;已服务14年&#xff0c;旨在帮助电商、传统批发零售和实体门店等业务群体提高订单处理效率和商业经营效益。 官网&#xff1a;https://www.wsgjp.com.cn/ 集简云无代码集成…

【ICCV‘23】One-shot Implicit Animatable Avatars with Model-based Priors

文章目录 前置知识 前置知识 1&#xff09;SMPL模型 \quad SMPL这类方法只建模穿很少衣服的人体&#xff08;裸体模型&#xff09;&#xff0c;它只能刻画裸体角色的动画&#xff0c;并不能刻画穿衣服的人体的动画 2&#xff09;data-efficient \quad 这个词推荐用&#xff…

解决SQLServer占用80端口问题

在安装好了SQLServer之后&#xff0c;发现系统默认80端口被占用&#xff0c;导致很多默认用80端口的软件运行不起来。 解决办法 1、运行(快捷键:WINR) services.msc 2、找到SQL Server Reporting Services (MSSQLSERVER) 服务 3、先停止服务&#xff0c;然后再禁用服务

使用MobaXterm向linux窗口化传输文件

使用MobaXterm向linux窗口化传输文件 之前上大学的时候&#xff0c;经常是XSheel配合Xftp使用&#xff0c;Xftp可以窗口化的往linux服务器传输文件&#xff0c;但是有一个问题&#xff0c;就是Xftp是收费的。 后来工作之后师兄给推荐了一个免费的&#xff0c;又好用的类似于Xf…

视频讲解|考虑源荷两侧不确定性的含风电电力系统低碳调度

目录 1 主要内容 2 讲解视频 1 主要内容 本次程序讲解对应程序链接考虑源荷两侧不确定性的含风电电力系统低碳调度&#xff0c;主要实现了基于模糊机会约束的源荷两侧不确定性对含风电电力系统低碳调度的影响&#xff0c;将源荷不确定性采用清晰等价类进行处理。部分讲解重点…

【23真题】邮电之首!扩招15倍!专业课难度骤降!

今天分享的是23年北京邮电大学804的信号与系统试题及解析。 本套试卷难度分析&#xff1a;北邮804在22年只招生6人&#xff0c;23年拟招生87人&#xff0c;扩招近15倍&#xff01;22年北京邮电大学804考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自…

Vant Weapp 的van-cell 与 van-cell-group的边框

场景&#xff1a; 用van-cell循环出来的单元格&#xff0c;最上面有一条边框线&#xff0c;且找不到该元素&#xff1b; <van-cell-group border"{{false}}"> 直接在这写属性 <van-cell> </van-cell> </van-cell-group> 效果图&#xff1…

探索无限可能!揭开泰拉瑞亚的神秘面纱

如果你是一位冒险家&#xff0c;喜欢探索未知的世界&#xff0c;那么你一定不能错过一款名为《泰拉瑞亚》的游戏。这是一款极具挑战性和趣味性的沙盒游戏&#xff0c;让你在探索中不断成长、发现新事物&#xff0c;最终成为一位无人能敌的探险家。 《泰拉瑞亚》是一款独特的游…