JavaScript 面向对象

news/2024/10/22 16:23:05/

一、对象

1.新建一个对象

// An object literal with two key-value pairs
let spaceship = {'Fuel Type': 'diesel',color: 'silver'
};

We separate each key-value pair in an object literal with a comma (,)

Keys are strings, but when we have a key that does not have any special characters in it, JavaScript allows us to omit the quotation marks

Keys are strings, but when we have a key that does not have any special characters in it, JavaScript allows us to omit the quotation marks

2.Accessing Properties 

我们可以用dot notation:

'hello'.length; // Returns 5

 也可以用这种方法:

let spaceship = {'Fuel Type': 'Turbo Fuel','Active Duty': true,homePlanet: 'Earth',numCrew: 5
};
spaceship['Active Duty'];   // Returns true
spaceship['Fuel Type'];   // Returns  'Turbo Fuel'
spaceship['numCrew'];   // Returns 5
spaceship['!!!!!!!!!!!!!!!'];   // Returns undefined

当属性名中包含特殊字符的时候(比如空格),只能用这种方法 ,不能用dot notation。该有的引号不能少。

我们还可以编写一个函数来得到希望的属性的值:

let returnAnyProp = (objectName, propName) => objectName[propName];returnAnyProp(spaceship, 'homePlanet'); // Returns 'Earth'

函数接受两个参数,分别代表希望得到属性的对象和希望得到的属性。

3.增删改属性

const spaceship = {type: 'shuttle'};
spaceship = {type: 'alien'}; // TypeError: Assignment to constant variable.
spaceship.type = 'alien'; // Changes the value of the type property
spaceship.speed = 'Mach 5'; // Creates a new key of 'speed' with a value of 'Mach 5'

4.给对象添加方法

可以用下面的两种语法来给对象写一个方法

const alienShip = {invade: function () { console.log('Hello! We have come to dominate your planet. Instead of Earth, it shall be called New Xaculon.')}
};
const alienShip = {invade () { console.log('Hello! We have come to dominate your planet. Instead of Earth, it shall be called New Xaculon.')}
};
alienShip.invade(); // Prints 'Hello! We have come to dominate your planet. Instead of Earth, it shall be called New Xaculon.'

当我们写多个方法时,不要忘记方法和方法之间的逗号:

let alienShip = {retreat() {console.log(retreatMessage)},takeOff() {console.log('Spim... Borp... Glix... Blastoff!')}
};

5.Nested Objects

const spaceship = {telescope: {yearBuilt: 2018,model: '91031-XLT',focalLength: 2032 },crew: {captain: { name: 'Sandra', degree: 'Computer Engineering', encourageTeam() { console.log('We got this!') } }},engine: {model: 'Nimbus2000'},nanoelectronics: {computer: {terabytes: 100,monitors: 'HD'},'back-up': {battery: 'Lithium',terabytes: 50}}
}; 

如果我们要访问属性:

spaceship.nanoelectronics['back-up'].battery; // Returns 'Lithium'

6.按引用传递

let spaceship = {homePlanet : 'Earth',color : 'red'
};
let tryReassignment = obj => {obj = {identified : false, 'transport type' : 'flying'}console.log(obj) // Prints {'identified': false, 'transport type': 'flying'}};
tryReassignment(spaceship) // The attempt at reassignment does not work.
spaceship // Still returns {homePlanet : 'Earth', color : 'red'};spaceship = {identified : false, 'transport type': 'flying'
}; // Regular reassignment still works.

`tryReassignment` 的函数接受一个对象作为参数。在 `tryReassignment` 函数中,尝试重新分配(reassignment)传入的对象 `obj`,将其设置为一个新的对象,改变原来的属性为新的属性: `{ identified: false, 'transport type': 'flying' }`。函数的参数为 `spaceship` 对象,因此尝试重新分配的是 `spaceship` 对象。

在这段代码中,`obj` 是一个函数参数,它是一个局部变量,只在函数中有效。当函数被调用时,`obj` 参数被赋值为传递给函数的实参 `spaceship` 的值,也就是 `spaceship` 对象的引用。因此,`obj` 和 `spaceship` 实际上引用了同一个对象。

在 `tryReassignment` 函数中,尝试重新分配 `obj`,将其设置为一个新的对象 `{ identified: false, 'transport type': 'flying' }`。这实际上是将 `obj` 的引用指向了一个新的对象,而不是修改了原始的 `spaceship` 对象。

因此,即使在 `tryReassignment` 函数中重新分配了 `obj`,原始的 `spaceship` 对象仍然保持不变。

因此,尽管在 `tryReassignment` 函数中重新分配了 `obj`,但原始的 `spaceship` 对象仍然保持不变。在函数调用后,`spaceship` 对象仍然是 `{ homePlanet: 'Earth', color: 'red' }`。

7.Looping Through Objects

js提供了for循环来直接遍历对象的属性。

let spaceship = {crew: {captain: { name: 'Lily', degree: 'Computer Engineering', cheerTeam() { console.log('You got this!') } },'chief officer': { name: 'Dan', degree: 'Aerospace Engineering', agree() { console.log('I agree, captain!') } },medic: { name: 'Clementine', degree: 'Physics', announce() { console.log(`Jets on!`) } },translator: {name: 'Shauna', degree: 'Conservation Science', powerFuel() { console.log('The tank is full!') } }}
}; // Write your code belowfor (let crewMember in spaceship.crew) {console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`)
};for (let crewMember in spaceship.crew) {console.log(`${spaceship.crew[crewMember].name}: ${spaceship.crew[crewMember].degree}`)
};
captain: Lily
chief officer: Dan
medic: Clementine
translator: Shauna
Lily: Computer Engineering
Dan: Aerospace Engineering
Clementine: Physics
Shauna: Conservation Science

let实际上是对各个属性重命名,for循环会自动把各个属性的名字赋给let后的crewMember

如何通过这种方法准确找到希望的属性非常重要!

如果把第二个for循环改成:

for (let crewMember in spaceship.crew) {console.log(`${crewMember.name}: ${spaceship.crew[crewMember].degree}`)
};

undefined: Computer Engineering

undefined: Aerospace Engineering

undefined: Physics

undefined: Conservation Science 

原因是crewMember= captain,chief officer,而不是spaceship.crew[captain],spaceship.crew[chief officer],所以直接打印crewMember.name等于打印caption.name,可是最外层并没有caption这个对象,最外层只有spaceship对象,所以结果是undefined。

而第一个for循环里,我们只希望打印captain和chief officer,相当于打印两个字符串,而不是通过caption的地址打印其他内容,所以可以不需要加外层的索引(spaceship.crew[~~~~])

8.review

  • Objects store collections of key-value pairs.
  • Each key-value pair is a property—when a property is a function it is known as a method.
  • An object literal is composed of comma-separated key-value pairs surrounded by curly braces.
  • You can access, add or edit a property within an object by using dot notation or bracket notation.
  • We can add methods to our object literals using key-value syntax with anonymous function expressions as values or by using the new ES6 method syntax.
  • We can navigate complex, nested objects by chaining operators.
  • Objects are mutable—we can change their properties even when they’re declared with const.
  • Objects are passed by reference— when we make changes to an object passed into a function, those changes are permanent.
  • We can iterate through objects using the For...in syntax.

9.this

我们可以用this关键字来访问本对象的其他属性:

const robot = {model:'1E78V2',energyLevel:100,provideInfo(){return `I am ${this.model} and my current energy level is ${this.energyLevel}.`}
};console.log(robot.provideInfo());
I am 1E78V2 and my current energy level is 100.

 注意:Arrow functions inherently bind, or tie, an already defined this value to the function itself that is NOT the calling object. In the code snippet above, the value of this is the global object, or an object that exists in the global scope, which doesn’t have a dietType property and therefore returns undefined.

const goat = {dietType: 'herbivore',makeSound() {console.log('baaa');},diet: () => {console.log(this.dietType);}
};goat.diet(); // Prints undefined

10.Privacy

One common convention is to place an underscore _ before the name of a property to mean that the property should not be altered. Here’s an example of using _ to prepend a property.

const bankAccount = {_amount: 1000
}

In the example above, the _amount is not intended to be directly manipulated.

Even so, it is still possible to reassign _amount:

bankAccount._amount = 1000000;

所以有-并不是强制不给更改了,只是表明我不希望你更改。

11.get方法

const person = {_firstName: 'John',_lastName: 'Doe',get fullName() {if (this._firstName && this._lastName){return `${this._firstName} ${this._lastName}`;} else {return 'Missing a first name or a last name.';}}
}// To call the getter method: 
person.fullName; // 'John Doe'

注意,get方法有自己的关键字get,当我们调用get方法的时候,我们不需要写括号,就好像我们在访问person的一个属性一样。

12.setter

const person = {_age: 37,set age(newAge){if (typeof newAge === 'number'){this._age = newAge;} else {console.log('You must assign a number to age');}}
};
person.age = 40;
console.log(person._age); // Logs: 40
person.age = '40'; // Logs: You must assign a number to age

setter也有自己的关键字,用setter赋值的时候,也不需要括号。

用getter和setter的一个好处是,可以对输入的类型做限定。

当然,我们也可以直接更改属性的内容,但是这样无法保证属性的类型:

person._age = 'forty-five'
console.log(person._age); // Prints forty-five

13.Factory Functions

我们可以用这种方式一次创建多个对象,有些像构造器

function robotFactory(model,mobile){return {model:model,mobile:mobile,beep(){console.log('Beep Boop');}}
}const tinCan=robotFactory('P-500',true)
tinCan.beep();
Beep Boop

我们还可以做如下简化:

const robotFactory = (model, mobile) => {return {model,mobile,beep() {console.log('Beep Boop');}}
}

 14.Object.keys()

 The Object.keys() static method returns an array of a given object's own enumerable string-keyed property names.

const object1 = {a: 'somestring',b: 42,c: false
};console.log(Object.keys(object1));
// Expected output: Array ["a", "b", "c"]

15.The Object.entries()

The Object.entries() static method returns an array of a given object's own enumerable string-keyed property key-value pairs.

const object1 = {a: 'somestring',b: 42
};for (const [key, value] of Object.entries(object1)) {console.log(`${key}: ${value}`);
}// Expected output:
// "a: somestring"
// "b: 42"

16.Object.assign() 

The Object.assign() static method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);
// Expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget === target);
// Expected output: true

17.review

  • The object that a method belongs to is called the calling object.
  • The this keyword refers to the calling object and can be used to access properties of the calling object.
  • Methods do not automatically have access to other internal properties of the calling object.
  • The value of this depends on where the this is being accessed from.
  • We cannot use arrow functions as methods if we want to access other internal properties.
  • JavaScript objects do not have built-in privacy, rather there are conventions to follow to notify other developers about the intent of the code.
  • The usage of an underscore before a property name means that the original developer did not intend for that property to be directly changed.
  • Setters and getter methods allow for more detailed ways of accessing and assigning properties.
  • Factory functions allow us to create object instances quickly and repeatedly.
  • There are different ways to use object destructuring: one way is the property value shorthand and another is destructured assignment.
  • As with any concept, it is a good skill to learn how to use the documentation with objects!

http://www.ppmy.cn/news/1000580.html

相关文章

【云原生】Kubernetes中deployment是什么?

目录 Deployments 更新 Deployment 回滚 Deployment 缩放 Deployment Deployment 状态 清理策略 金丝雀部署 编写 Deployment 规约 Deployments 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力。 你负责描述 Deployment 中的 目标状态,而 De…

C# 文件读写 程序

//读写文件 public class ReadWriteFile { public static List<string> ReadFile(string path) { try { using (FileStream fileStream new FileStream(path, FileMode.Open, FileAccess.Read)) { Lis…

【Java多线程学习5】什么是悲观锁,什么是乐观锁?如何实现乐观锁、乐观锁存在哪些问题

【Java多线程学习5】什么是悲观锁&#xff0c;什么是乐观锁&#xff1f;如何实现乐观锁、乐观锁存在哪些问题 一、什么是悲观锁 概述 悲观锁总是假设最坏的情况&#xff0c;认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改)&#xff0c;所以每次在获取资源操作…

docker: Error response from daemon: No command specified.

执行 docker run -it -d -v /home/dell/workspace/workspace/test_192.168.1.202_pipeline:/home/workspace1 --name test_192.168.1.202_pipeline_10 qnx:7.1报错 问题定位&#xff1a;export导入的镜像需要带上command&#xff0c;以下命令查看command信息 docker ps --no…

RelativeSource有四种类型

Self FindAncestor TemplatedParent PreviousData a.Self Self用于绑定源和绑定目标相同的场景中。对象的一个属性与同一对象的另一个属性绑定。 例如&#xff0c;让我们取一个高度和宽度相同的椭圆。在XAML文件中添加下面给出的代码。宽度属性与高度属性相对绑定。 <G…

【搜索】DFS搜索顺序

算法提高课笔记 目录 马走日题意思路代码 单词接龙题意思路代码 分成互质组题意思路代码 马走日 原题链接 马在中国象棋以日字形规则移动。 请编写一段程序&#xff0c;给定 n∗m 大小的棋盘&#xff0c;以及马的初始位置 (x&#xff0c;y)&#xff0c;要求不能重复经过棋盘…

Python的字典使用

今天做力扣上1207. 独一无二的出现次数添加链接描述时用到了python字典&#xff0c;于是把字典的用法整理了一下。 新建字典 iters {}检查字典中是否含有某一个键 iters.has_key(key)字典根据键访问值 iters[key]遍历字典的键和值 for key,value in iters.items():整体代码 c…

Ubuntu20.04之VNC的安装与使用

本教程适用于Ubuntu20.04及以下版本&#xff0c;Ubuntu22.04版本或有出入 更多更新的文章详见我的个人博客&#xff1a;【前往】 文章目录 1.安装图形桌面1.1选择安装gnome桌面1.2选择安装xface桌面 2.安装VNC-Server3.配置VCN-Server4.连接VNC5.设置VNC-Server为系统服务&…