点击蓝字
关注我们
始于理论,源于实践,终于实战
老付话安全,每天一点点
激情永无限,进步看得见
严正声明
本号所写文章方法和工具只用于学习和交流,严禁使用文章所述内容中的方法未经许可的情况下对生产系统进行方法验证实施,发生一切问题由相关个人承担法律责任,其与本号无关。
特此声明!!!
什么是 JavaScript 中的对象
在 JavaScript 中,对象是一种数据结构,用于存储键值对(key-value pairs)。对象可以包含属性(properties)(对象的属性是键值对,键是属性名,值是属性值。属性值可以是任何数据类型,包括其他对象、数组、函数等。)和方法(methods)(对象的方法是包含函数定义的属性。方法可以在对象上调用,执行特定的操作),其中属性是对象的数据,而方法是对象的行为。
JavaScript 中对象的创建方式:
1、对象字面量:使用花括号 {} 来定义对象。
let person = {
firstName: "John",
lastName: "Doe",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
}
};
2、构造函数:使用 new 关键字和构造函数来创建对象。
function Person(firstName, lastName, age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.greet = function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
};
}
let person = new Person("John", "Doe", 30);
3、ES6 类:使用 ES6 引入的类语法来创建对象。
classPerson{
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
greet() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
}
}
let person = new Person("John", "Doe", 30);
访问和操作对象:
使用点符号 . 或方括号 [] 来访问对象的属性。
console.log(person.firstName); // 输出: John
console.log(person['lastName']); // 输出: Doe
调用方法:使用点符号 . 来调用对象的方法。
person.greet(); // 输出: Hello, my name is John Doe
添加和修改属性:可以直接赋值来添加或修改对象的属性。
person.age = 31; // 修改属性
person.email = "[email protected]"; // 添加新属性
删除属性:使用 delete 关键字来删除对象的属性。
delete person.email; // 删除属性
常见的内置对象:
JavaScript 提供了许多内置对象,例如:
-
JSON:用于解析和序列化 JSON 数据。
-
Math:提供数学常数和函数。
-
Date:用于处理日期和时间。
-
Array:用于处理数组。
-
String:用于处理字符串。
什么是 JavaScript 中的原型
在 JavaScript 中,原型是实现继承的主要机制。每个函数在创建时都会自动获得一个 prototype 属性,这个属性指向一个对象,即该函数的原型对象。原型对象可以包含属性和方法,这些属性和方法可以被所有使用该函数作为构造函数创建的对象所共享。
原型对象的创建
当声明一个函数时,JavaScript 引擎会自动创建一个原型对象,并将其赋值给该函数的 prototype 属性。例如:
function Person(){}
在这个例子中,Person 函数有一个 prototype 属性,它指向一个原型对象。这个原型对象有一个默认的属性 constructor,它的值是 Person 函数本身。
使用原型对象
当你使用 new 关键字调用构造函数创建对象时,新创建的对象会有一个内部属性 [[Prototype]],它指向构造函数的原型对象。例如:
let p1 = new Person();
在这个例子中,p1 对象的 [[Prototype]] 属性指向 Person.prototype 。这意味着 p1 可以访问 Person.prototype 上定义的属性和方法。
JavaScript 的原型链是一种通过原型对象实现继承的机制。每个对象都有一个原型对象,当访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(即 null)。原型对象本身也是一个对象,因此它也有自己的原型。这种原型关系形成了一个链状结构,称为原型链。原型链的顶端是 Object.prototype ,所有的原型链最终都会指向 Object.prototype ,因为所有对象都是从 Object 继承来的。Object.prototype 的原型是 null,表示原型链的终点。它提供了许多常用的方法,如 toString() 和 valueOf()。最终,所有的原型链都会终止于 null。
即对象的 prototype 只是另一个对象,它也应该有自己的 prototype,依此类推。由于 JavaScript 中的几乎所有内容在后台都是一个对象,因此这条链最终会回到顶级的 Object.prototype,其原型是 null。重要的是,对象不仅从其直接原型继承属性,还从原型链中位于其上方的所有对象继承属性。
例如:
function Person(name){
this.name = name;
}
Person.prototype.greet = function() {
console.log('Hello, my name is ' + this.name);
};
let p1 = new Person('Alice');
p1.greet(); // 输出: Hello, my name is Alice
在这个示例中,Person 函数的原型对象上定义了一个 greet 方法。所有使用 Person 构造函数创建的对象都可以访问这个 greet 方法。
修改原型对象
可以随时修改原型对象,所有使用该构造函数创建的对象都会立即反映出这些变化。例如:
Person.prototype.age = 25;
console.log(p1.age); // 输出: 25
在这个例子中,我们在 Person.prototype 上添加了一个 age 属性,所有 Person 实例都可以访问这个属性。
像修改任何其他对象一样修改 JavaScript 的内置原型,意味着开发人员可以自定义或覆盖内置方法的行为,甚至可以添加新方法来执行有用的操作。如:JavaScript 为字符串提供了 trim() 方法,它使你能够轻松删除任何前导或尾随空格。在引入此内置方法之前,开发人员有时会通过执行以下操作将此行为的自定义实现添加到 String.prototype 对象中:
String.prototype.removeWhitespace = function(){
returnthis.replace(/s/g, '');
};
使用了正则表达式/s/g,s表示空白字符(包括空格、制表符、换行符等),g表示全局匹配,replace方法会将所有匹配到的空白字符替换为空字符串。删除前导或尾随空格
有了原型继承,所有字符串都可以访问此方法:
let searchTerm = " example ";
searchTerm = searchTerm.removeWhitespace();
console.log(searchTerm);
这里将searchTerm重新赋值为调用removeWhitespace方法后的结果,这样就得到了去除空白字符后的字符串。
JavaScript 中的每个对象都链接到某种类型的另一个对象,称为其原型。默认情况下,JavaScript 会自动为新对象分配其内置原型之一。例如,字符串会自动分配内置的 String.prototype。例如:
let myObject = {};
Object.getPrototypeOf(myObject); // 对象原型
let myString = "";
Object.getPrototypeOf(myString); // 字符串原型
let myArray = [];
Object.getPrototypeOf(myArray); // 数组原型
let myNumber = 1;
Object.getPrototypeOf(myNumber); // 数字原型
对象会自动继承其分配的原型的所有属性,除非它们已经拥有具有相同键的自己的属性。这使开发人员能够创建可以重用现有对象的属性和方法的新对象。
内置原型为处理基本数据类型提供了有用的属性和方法。例如,String.prototype 对象具有 toLowerCase() 方法。因此,所有字符串都会自动获得将其转换为小写的现成方法。这样,开发人员就不必手动将此行为添加到他们创建的每个新字符串中。
对象继承在 JavaScript 中是如何工作的
在JavaScript中,对象继承主要基于原型链(prototype chain)。每个对象都有一个内部属性[[Prototype]](在大多数浏览器中可以通过__proto__属性访问,但这不是标准属性,标准方式是使用Object.getPrototypeOf() )。当我们访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript会沿着原型链向上查找,直到找到该属性或者到达原型链的顶端(Object.prototype ,它的原型为null)。
每当引用对象的属性时,JavaScript 引擎首先会尝试直接在对象本身上访问它。如果对象没有 matching 属性,则 JavaScript 引擎会改为在对象的原型上查找它。
在浏览器控制台查看对象引用的实际效果。首先,创建一个完全空的对象:
即使没有为对象本身定义任何属性或方法,它也从内置的 Object.prototype 继承了一些属性或方法。
使用 __proto__ 访问对象的原型
每个对象都有一个特殊属性,可以使用该属性来访问其原型。虽然它没有正式的标准化名称,但 __proto__ 是大多数浏览器使用的事实标准。如果熟悉面向对象的语言,则此属性将用作对象原型的 getter 和 setter。这意味着您可以使用它来读取原型及其属性,甚至在必要时重新分配它们。
可以使用方括号或点表示法访问 __proto__:
username.__proto__
username['__proto__']
可以将引用链接到 __proto__ 中,以便在原型链中向上工作:
username.__proto__ // 字符串模型
username.__proto__.__proto__ // 对象模型
username.__proto__.__proto__.__proto__ // null
END
老付
欢迎扫码
关注我们
网络安全
原文始发于微信公众号(老付话安全):JavaScript原型与继承的基础知识
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论