Table of contents
1. Constructor
1. Function: Create objects.
Return an object through a normal function:
function createPerson(firstName, lastName) {
var obj = {
}
obj.firstName = firstName
obj.lastName = lastName
obj.fullName = firstName + lastName
obj.myName = function () {
console.log(obj.fullName)
}
return obj
}
const person = createPerson('张', '三')
Create object through constructor
function Person(firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
this.fullName = firstName + lastName
this.myName = function () {
console.log(this.fullName)
}
}
const person = new Person('张', '三') // 规定语法
2. All objects in js are created through constructors.
Object() constructor , sotypeof Object === 'function'
var obj = {
age: 18
}
// 上面是语法糖
var obj = new Object()
obj.age = 18
Each js function is actually a Function object when created through Function
the constructor (you can not add new
the keyword).
const add= new Function("a", "b", "return a + b");
add(2, 6);
2. Prototype
When a method is defined in a constructor, a new method is created each time because each constructed instance is independent.
function Foo(a, b) {
this.a = a
this.b = b
this.sayHi = function () {
console.log(this.a + this.b)
}
}
const foo1 = new Foo(1, 2)
const foo2 = new Foo(1, 2)
console.log(foo1.sayHi === foo2.sayHi) // false
This would cause a waste of memory space, so prototypes emerged to solve this problem.
When accessing an instance member, look for itself first. If it does not exist, it will automatically look for it from the implicit prototype.
The prototype is also an object , and public methods are generally placed on the prototype.
function Foo(a, b) {
this.a = a
this.b = b
}
Foo.prototype.sayHi = function () {
console.log(this.a + this.b)
}
const foo1 = new Foo(1, 2)
const foo2 = new Foo(1, 2)
console.log(foo1.sayHi === foo2.sayHi) // true
3,this
1. Use this in a function. Its direction depends entirely on how the function is called . Specific reference
For example, add the print method to all objects and print the key-value pairs of the objects.
Object.prototype.print = function () {
for (var key in this) {
// 过滤掉 print
if (this.hasOwnProperty(key)) {
console.log(key, this[key])
}
}
}
var obj = {
a: 1,
b: 2
}
console.log(obj.print())
Indicates whether the specified property is present in the object's own properties (rather than inherited properties).
3. in operator
Determine whether the attribute name is on the object itself and its prototype chain.
4. Prototype chain
1. Features
-
Object.prototype
Object()
What's special is that it is not created through the constructor, but is one of the basic objects automatically created when the JavaScript engine is initialized. (Answer from GPT4) Adding attributes
onObject.prototype
will affect all objects (including functions and arrays). -
Adding
Function.prototype
attributes to will affect all functions, so you can determine whether a variable is a function.
Function.prototype.isFun = true
var obj = {
}
function fun() {
}
console.log(obj.isFun) // undefined
console.log(fun.isFun) // true
- Little known fact,
Array.prototype
is an array and not an object. AlthoughArray.prototype.__proto__ === Object.prototype
2,Object.prototype.toString()
MDN - Object.prototype.toString()
The object will be converted to string format [object Object]
, but this format is not what every object wants.
So the array overrides toString
the method
Array.prototype.toString === Object.prototype.toString // false
How to make the array's toString method use Object.prototype.toString
const arr = [1,2,3]
Object.prototype.toString.call(arr)
So how to determine whether a variable is an array :
const arr = [];
console.log(Object.prototype.toString.call(arr)); // [object Array]
If your own constructor wants to change toString, how to change it?
function User() {
}
const user = new User();
User.prototype.toString = function () {
return "xxx";
};
console.log(user.toString()); // xxx
3. instanceof operator
Used to detect whether the prototype of the constructor appears on the prototype chain of an instance object.
function User() {
}
var user = new User()
console.log(user instanceof User) // true
console.log(user instanceof Object) // true
o in C
More used to determine whether the object is an instance created by o
the constructor .C
So, it can be understood like this:
obj instanceof Array // obj 是不是数组
obj instanceof Object // obj 是不是对象
obj instanceof Function // obj 是不是函数
4,Object.getPrototypeOf()
Because it is deprecated __proto__
, there are new ways to manipulate implicit prototypes: Object.getPrototypeOf()
andObject.setPrototypeOf()
const arr = [];
console.log(Object.getPrototypeOf(arr) === arr.__proto__); // true
5. Create an empty prototype object
method 1,
const obj = {
}
obj.__proto__ = null // 不推荐 直接操作 __proto__
Object.setPrototypeOf(obj, null) // 可以使用
Way 2,
const obj = Object.create(null)
6. Interview questions
The following interview questions can be quickly explained using the prototype chain diagram above.
// 下面的代码输出什么?(京东)
Function.prototype.a = 1;
Object.prototype.b = 2;
function A() {
}
var a = new A();
console.log(a.a, a.b); // undefined 2
console.log(A.a, A.b); // 1 2
// 下面的代码输出什么?(字节)
console.log({
} instanceof Object); // true
console.log({
}.toString instanceof Function); // true
console.log(Object instanceof Function); // true
console.log(Function instanceof Object); // true
// 下面的代码输出什么?
function User() {
}
User.prototype.sayHello = function () {
};
var u1 = new User();
var u2 = new User();
console.log(u1.sayHello === u2.sayHello); // true
console.log(User.prototype === Function.prototype); // false
console.log(User.__proto__ === Function.prototype); // true
console.log(User.__proto__ === Function.__proto__); // true
console.log(u1.__proto__ === u2.__proto__); // true
console.log(u1.__proto__ === User.__proto__); // false
console.log(Function.__proto__ === Object.__proto__); // true
console.log(Function.prototype.__proto__ === Object.prototype.__proto__); // false
console.log(Function.prototype.__proto__ === Object.prototype); // true
5. Inheritance
Suppose there is a membership system
- free user
- Properties: username, password
- How to: Play Free Videos
- vip user
- Attributes: There is also membership expiration time
- Method: There is also a way to play VIP videos
function User(name, pwd) {
this.name = name
this.pwd = pwd
}
User.prototype.playFreeVideo = function() {
console.log('免费视频');
}
function VipUser(name, pwd, expires) {
this.name = name
this.pwd = pwd
this.expires = expires
}
VipUser.prototype.playFreeVideo = function() {
console.log('免费视频');
}
VipUser.prototype.playVipVideo = function() {
console.log('vip视频');
}
You can see redundant code. Under transformation
1. Handle duplication inside the constructor.
function VipUser(name, pwd, expires) {
User.call(this, name, pwd)
this.expires = expires
}
2. Deal with duplication on prototypes
A diagram is needed to show the relationship
// VipUser.prototype.__proto__ = User.prototype
Object.setPrototypeOf(VipUser.prototype, User.prototype)
Inheritance is the above relationship.
- Instances of subclasses should automatically have all members of the parent class.
- A subclass can have at most one parent class
- Indirect members of the parent class will be passed to the child class
encapsulating inheritance
function inherit(Child, Parent) {
Object.setPrototypeOf(Child.prototype, Parent.Parent)
}