在JS中我们可以通过以下方式进行创建对象:
var obj =
{
name:"孙悟空",
age:18,
gender:"男",
sayName:function()
{
alert(this.name);
}
};
var obj2 =
{
name:"猪八戒",
age:28,
gender:"男",
sayName:function()
{
alert(this.name);
}
};
var obj3 =
{
name:"沙和尚",
age:38,
gender:"男",
sayName:function()
{
alert(this.name);
}
};
obj.sayName();
obj2.sayName();
obj3.sayName();
但是这样去创建对象我们发现一个问题没有,那么假设我们每次去创建一个对象,都需要重复写很多代码,而我们开发中会有很多对象,当然这个需要后端的配合,但是假设我们纯纯在前端创建多个对象,而不调用后端的给我们的对象,那么我们应该如何操作呢?
这个时候我们可以通过工厂的方法创建对象,通过这种方式,我们可以大批量的创建对象。
//通过工厂方法创建对象
//通过该方法可以大批量的创建对象
function createPerson(name,age,gender)
{
//在函数中创建一个新的对象
var obj =new Object();
//向对象中添加属性
obj.name="孙悟空";
obj.age=18;
obj.gender="男";
//将新的对象返回
return obj;
}
var obj2 =createPerson("孙悟空",18,"男");
console.log(obj2);
function createDog(name,age)
{
var obj=new Object();
obj.name=name;
obj.age=age;
obj.sayHello=function()
{
alert(this.name);
};
return obj;
}
var obj3 =createDog("砖家",3);
console.log(obj3);
//使用工厂方法创建的对象,使用的构造函数都是Object
//所以创建的对象都是Object这个类型
//就导致我们无法区分出多种不同类型的对象
实际上就是对一个函数的重复利用,利用函数中我们定义的变量,我们只需要把我们需要的条件塞进工厂,工厂按照他内部的逻辑给我们处理达到我们想要的功能或者数据。
构造函数是一种特殊的函数,用于初始化对象的属性和方法。但创建方式和普通函数没有区别**,不同的是构造函数习惯上首字母大写
构造函数的执行流程
使用同一个构造函数创建的对象,称之为一类对象,也将一个构造函数称为一个类
我们将通过一个构造函数创建的对象,称为是该类的实例
function Person(name,age,gender)
{
this.name=name;
this.age=age;
this.gender=gender;
}
var per=new Person("砖家",18,"男");
console.log(per);
//使用instanceof可以检查一个对象是否是一个类的实例
//如果是,则返回true,如果不是,则返回false
//所有的对象都是Object的后代,所以任何对象和Object做instanceof检查时都会返回true

创建一个Person构造函数,在Person构造函数中,为每一个对象添加了一个sayName方法,目前我们的方法是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的SayName方法,也就是所有实例的sayName都是唯一的
,这样就导致了构造函数执行一次就会创建一个新的方法,执行10000次就会创建10000个新的方法,而10000个方法都是一模一样的,这是完全没有必要的,完全可以是所有的对象共享一个同一个方法,将方法提取出来,然后用赋值方法来引用。
function Person(name,age,gender)
{
this.name=name;
this.age=age;
this.gender=gender;
//向对象中添加一个方法
this.sayName=fun;
}
//将sayName方法在全局作用域中定义
//将函数定义在全局作用域,污染了全局作用域的命名空间
function fun()
{
alert(this.name);
}
var per=new Person("鲁智深",18,"男");
var per2=new Person("宋江",1,"男");
per.sayName();
per2.sayName();
console.log(per);
console.log(per2);
上述代码就是根据创建的构造函数,依次弹窗展示名字。
原型模式(Prototype Pattern)是一种常用的设计模式,用于创建对象的克隆副本。它通过使用原型对象作为模板,然后通过克隆来创建新的对象,避免了重复创建相似对象的开销。
// 原型对象
var personPrototype = {
name: "Unknown",
age: 0,
greet: function() {
console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
}
};
// 使用原型对象创建新的对象
var person1 = Object.create(personPrototype);
person1.name = "Alice";
person1.age = 25;
var person2 = Object.create(personPrototype);
person2.name = "鲍勃";
person2.age = 30;
// 调用对象的方法
person1.greet(); // 输出 "Hello, my name is Alice and I am 25 years old."
person2.greet(); // 输出 "Hello, my name is 鲍勃 and I am 30 years old."
提到垃级回收机制,我们如果对后端语言有所了解的话,Java中的自动回收机制和C语言的手动回收机制都会有点印象。这里我们提及一下JS的垃级回收机制:
标记-清除算法:
引用计数:
循环引用:
垃圾回收器的触发时机:
垃圾回收器的触发时机是由 JavaScript 引擎决定的,通常在以下情况下触发:
数组(Array)是一种用于存储多个值的有序集合。它是一种非常常用的数据结构,用于处理和操作一组相关的数据。
创建数组:
访问和修改数组元素:
数组长度:
数组方法:
遍历数组:
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
arr.forEach(function(element) {
console.log(element);
});
多维数组:
数组方法的操作:
push():
push() 方法向数组的末尾添加一个或多个元素,并返回新数组的长度。
例如:arr.push(4);
pop():
pop() 方法从数组的末尾移除最后一个元素,并返回被移除的元素。
例如:let removedElement = arr.pop();
shift():
shift() 方法从数组的开头移除第一个元素,并返回被移除的元素。
例如:let removedElement = arr.shift();
unshift():
unshift() 方法向数组的开头添加一个或多个元素,并返回新数组的长度。
例如:arr.unshift(0);
slice():
slice() 方法返回一个新数组,其中包含从开始索引到结束索引(不包括结束索引)的元素。
例如:let slicedArr = arr.slice(1, 3);
splice():
splice() 方法可以用于删除、替换或插入数组中的元素,并返回被删除的元素。
例如:let removedElements =arr.splice(1, 2);
concat():
concat() 方法用于合并两个或多个数组,并返回一个新数组。
例如:let newArr = arr.concat([4, 5]);
join():
join() 方法将数组的所有元素连接成一个字符串,并返回该字符串。
例如:let str = arr.join(", ");
sort():
sort() 方法用于对数组进行排序,默认按照字符串的 Unicode 编码进行排序。
例如:arr.sort();
reverse():
reverse() 方法用于颠倒数组中元素的顺序。
例如:arr.reverse();