前端学习笔记JavaScript - 类和对象
三大特性
封装
封装性就是隐藏实现细节,仅对外提供接口。
function Test() {
this.name = 1; // -- 私有属性,外部无法访问
let age = 30; // -- 私有属性,外部无法访问
// -- 提供共有方法设置属性
this.setAge = function (myAge) {
if (myAge > 0 ){
age = myAge;
}
}
// -- 提供公有方法获取属性
this.getAge = function () {
return age;
}
// -- 私有方法
function say() {
console.log("唱歌");
}
}
let obj1 = new Test();
obj1.name = "zs";
obj1.setAge(23);
console.log(obj1.getAge());
属性和方法的分类
- 实例属性/实例方法
通过实例对象访问的属性 - 实例属性
通过实例对象调用的方法 - 实例方法
- 静态属性/静态方法
通过构造函数访问的属性 - 静态属性
通过构造函数调用的方法 - 静态方法
function Person(myName) {
this.name = myName;
this.say = function () {
console.log("唱歌");
}
}
let obj1 = new Person("zs")
// -- 实例属性
console.log(obj1.name);
// -- 实例方法
obj1.say();
// -- 静态属性
Person.age = 12;
console.log(Person.age);
// -- 静态方法
Person.run = function () {
console.log("跑");
}
Person.run();
继承
bind - call - apply
用于修改函数中的this
bind
修改函数或方法中的this为指定对象,并会返回一个修改之后的新函数。
注意:bind除了可以修改this以外,还可以传递参数,只不过参数必须写在this对象后面。
let obj = {
name: "zs"
}
function Person(myName,myAge) {
console.log(myName);
}
let fn = Person.bind(obj,"ls",12);
fn()
call
修改函数或方法中的this为指定对象,并会立即调用修改后的函数。
注意:bind除了可以修改this以外,还可以传递参数,只不过参数必须写在this对象后面。
let obj = {
name: "zs"
}
function Person(myName,myAge) {
console.log(myName);
}
Person.call(obj,"ls",12);
apply
修改函数或方法中的this为指定对象,并会立即调用修改后的函数。
注意:bind除了可以修改this以外,还可以传递参数,只不过参数必须写在this对象后面。(参数传递格式和call不一样,其他都一样)
let obj = {
name: "zs"
}
function Person(myName,myAge) {
console.log(myName);
}
Person.apply(obj,["ls",12]);
- 继承方式
- 在子类的构造函数中通过call借助父类的构造函数
- 将子类的原型对象修改为父类的实例对象
function Person(myName,myAge) {
this.name = myName;
this.age = myAge;
this.go = function () {
console.log("gogogo");
}
}
Person.prototype.run = function () {
console.log("运动会");
}
Person.prototype.height = 175;
function Student(myName,myAge,mySourde) {
// -- 在子类的构造函数中通过call借助父类的构造函数
Person.call(this,myName,myAge);
this.sourd = mySourde;
this.say = function () {
console.log("好好学习");
}
}
// -- 将子类的原型对象修改为父类的实例对象 , 就可以访问父类的prototype的属性和方法
Student.prototype = new Person();
Student.prototype.constructor = Student;
let xiaoMing = new Student("XH",12,99);
console.log(xiaoMing.name + xiaoMing.age + xiaoMing.sourd);
xiaoMing.say();
xiaoMing.go();
xiaoMing.run();
console.log(xiaoMing.height);
多态
ES6类和对象
ES6中定义类
注意
- 在ES6标准中,添加实例属性都需要再constructor中添加
class Person {
// -- 传递参数
constructor(myName,myAge) {
// -- 实例属性
this.name = "zs";
this.age = 11;
// -- 实例方法
this.run = function () {
console.log("跑");
}
}
// -- 实例方法(添加到原型中)
say(){
console.log(this.name,this.age);
}
// -- 静态方法
static eat(){
console.log("回锅肉");
}
}
let xiaoMing = new Person("zs",12);
xiaoMing.say();
xiaoMing.run();
Person.love = 175;
Person.eat();
console.log(Person.love);
ES6继承
class Person {
constructor(myName,myAge) {
this.name = myName;
this.age = myAge;
}
say(){
console.log(this.name, this.age);
}
}
// -- Student继承Person
class Student extends Person {
constructor(myName,myAge,mySoure) {
// -- 在子类中通过call,bind借助父类的构造函数
super(myName,myAge);
this.soure = mySoure;
}
}
let stu = new Student("ls",44,100);
stu.say();
获取对象的真实类型
let list = [];
let obj = {};
console.log(list.constructor.name);
console.log(obj.constructor.name);
instanceof
判断对象是否是指定函数的实例
function Person() {
}
function Student() {
}
let p = new Person();
let s = new Student();
console.log(p instanceof Person);
console.log(s instanceof Person);
isPrototypeOf
isPrototypeOf用于判断一个对象是否是指定对象的原型
function Person() {
}
function Student() {
}
let p = new Person();
let s = new Student();
console.log(Person.prototype.isPrototypeOf(p));
console.log(Person.prototype.isPrototypeOf(s));
判断对象属性
in
既会判断类中有没有对应的属性,还会判断prototype中是否有对应属性。
function Person() {
this.name = 'ZS';
}
Person.prototype.age = 12;
let p = new Person();
console.log("name" in p);
console.log("age" in p);
console.log("height" in p);
hasOwnProperty
只会判断类中是否有对应属性
function Person() {
this.name = 'ZS';
}
Person.prototype.age = 12;
let p = new Person();
console.log(p.hasOwnProperty("name"));
console.log(p.hasOwnProperty("age"))
对象遍历
使用for in 循环来遍历obj,取出所有的属性和方法
注意点:无法取出原型对象中的属性和方法。
function Person(myName, myAge){
this.name = myName;
this.age = myAge;
this.say = function(){
console.log(this.name, this.age);
}
}
let p = new Person("LNJ", 34);
console.log(p);
for(let key in p){
if(p[key] instanceof Function){
continue;
}
// console.log(key); // name / age / say
// 注意点: 以下代码的含义取出p对象中名称叫做当前遍历到的名称的属性或者方法的取值
console.log(p[key]); // p["name"] / p["age"] / p["say"]
// 注意点: 以下代码的含义取出p对象中名称叫做key的属性的取值
// console.log(p.key); // undefined
}
对象的解构赋值
注意点:在对象解构赋值中, 左边的变量名称必须和对象的属性名称一致, 才能解构出数据
let {name,age} = {name:"zs",age:12}
console.log(name, age);
深拷贝和浅拷贝
- 深拷贝
修改新变量的值不会影响原有变量的值
默认情况下基本数据类型都是深拷贝
let num1 = 11;
let num2 = num1;
num2 = 34;
console.log(num1, num2);
- 浅拷贝
修改新变量的值会影响原有变量的值
默认情况下引用类型都是浅拷贝
let obj = {
name:"zs",
age:12
}
let obj1 = obj;
obj1.name = "ls";
console.log(obj.name, obj1.name);
- assign()
assign方法可以把第二个参数的对象和方法拷贝到第一个对象中
let obj = {
name:"zs",
age:12
}
let obj1 = new Object();
Object.assign(obj1,obj)
obj1.name = "ls";
console.log(obj.name, obj1.name);
- 对象深拷贝
class Person{
name = "lnj";
cat = {
age : 3
};
scores = [1, 3, 5];
}
let p1 = new Person();
let p2 = new Object();
depCopy(p2, p1);
// console.log(p2);
p2.cat.age = 666;
console.log(p1.cat.age);
console.log(p2.cat.age);
function depCopy(target, source) {
// 1.通过遍历拿到source中所有的属性
for(let key in source){
// console.log(key);
// 2.取出当前遍历到的属性对应的取值
let sourceValue = source[key];
// console.log(sourceValue);
// 3.判断当前的取值是否是引用数据类型
if(sourceValue instanceof Object){
// console.log(sourceValue.constructor);
// console.log(new sourceValue.constructor);
let subTarget = new sourceValue.constructor;
target[key] = subTarget;
depCopy(subTarget, sourceValue);
}else{
target[key] = sourceValue;
}
}
}
数组高级API
- 遍历数组 - for of
for (let num of arr) {
console.log(num);
}
- 遍历数组 - forEach
let arr = [1,3,4,5];
arr.forEach(function (listValue,listIndex,list) {
console.log(listValue, listIndex, list);
})
// -- 内部实现方式
let arr = [1,3,4,5];
Array.prototype.myForEach = function (fn) {
for (let i = 0; i < this.length; i++) {
fn(this[i], i, this);
}
}
arr.myForEach(function (listValue,listIndex,list) {
console.log(listValue, listIndex, list);
})
- 查找元素 - findIndex
// 1.数组的findIndex方法
// findIndex方法: 定制版的indexOf, 找到返回索引, 找不到返回-1
let index = arr.findIndex(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
// if(currentValue === 6){
if(currentValue === 10){
return true;
}
});
console.log(index);
- 查找元素 - find
// 2.数组的find方法
// find方法返回索引, find方法返回找到的元素
// find方法如果找到了就返回找到的元素, 如果找不到就返回undefined
let value = arr.find(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
// if(currentValue === 6){
if(currentValue === 10){
return true;
}
});
console.log(value);
- 将满足的元素添加到新的数组 - filter
// 1.数组的filter方法:
// 将满足条件的元素添加到一个新的数组中
let newArray = arr.filter(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
if(currentValue % 2 === 0){
return true;
}
});
console.log(newArray); // [2, 4]
- 将满足条件的元素映射到新的数组
// 2.数组的map方法:
// 将满足条件的元素映射到一个新的数组中
let newArray = arr.map(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
if(currentValue % 2 === 0){
return currentValue;
}
});
console.log(newArray); // [undefined, 2, undefined, 4, undefined]
- 数组排序
// let arr = ["c", "a", "b"];
// arr.sort();
/*
如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前
注意点: 如果元素是字符串类型, 那么比较的是字符串的Unicode编码
*/
/*
arr.sort(function (a, b) {
if(a > b){
return -1;
}else if(a < b){
return 1;
}else{
return 0;
}
});
console.log(arr);
*/
/*
let arr = [3, 4, 2, 5, 1];
// arr.sort();
arr.sort(function (a, b) {
// if(a > b){
// return -1;
// }else if(a < b){
// return 1;
// }else{
// return 0;
// }
// 规律: 如果数组中的元素是数值类型
// 如果需要升序排序, 那么就返回a - b;
// 如果需要降序排序, 那么就返回b - a;
// return a - b;
return b - a;
});
console.log(arr);
*/
/*
let arr = ["1234", "21", "54321", "123", "6"];
arr.sort(function (str1, str2) {
// return str1.length - str2.length;
return str2.length - str1.length;
});
console.log(arr);
*/
let students = [
{name: "zs", age: 34},
{name: "ls", age: 18},
{name: "ww", age: 22},
{name: "mm", age: 28},
];
students.sort(function (o1, o2) {
// return o1.age - o2.age;
return o2.age - o1.age;
});
console.log(students);

浙公网安备 33010602011771号