OOP
类 在JS中也叫构造器 构造函数,对象是属性的无序集合
只要是对象,必定有有一个__proto__属性,隐式原型 在新版浏览器中显示为[[Prototype]]
- a.b 找a 去自己的EC中找a 如果找不到就去父的EC中找,一直找到ECG 如果ECG中没有就报 a is not defined(作用域链);找b,先找自己的私有属性,找不到去__proto__公有属性上找,如果一直找不到就返回undefined
- _ _ proto _ _对应的值是一个对象,这个对象叫原型对象,如果一直找下去,返回null
私有属性
公有属性
- _ _ proto_ _
- __proto__下的属性都是公有属性
- hasOwnProperty 判断一个属性是否是私有属性
- hasOwnProperty 是__proto__的私有属性
- in 判断一个属性是否属于某个对象 不管私有还是公有 'push' in arr
- prototype
- 每个构造函数(类)上 都有prototype属性 显式原型
- 显式原型和隐式原型指向同一个原型对象
创建对象的两种方式
- new 是一个运算符 new一个类 会得到一个对象
- 通过构造器new一个对象,也会造成内存空间浪费
- 在构造器中创建一个新对象
- 这个对象的prototype属性会被赋值为该构造函数的prototype属性
- 让构造器中的this指向这个创建的新对象
- 如果构造器没有返回对象,则返回创建的新对象
function Person(name,age){
this.name = name
this.age = age
this.say = ()=>{console.info('我叫'+this.name+',今年'+this.age+'岁')}
}
let zf = new Person('张飞',29)
let gy = new Person('关羽',33)
zf instanceof Person //true
- 字面量
- 有大量的重复代码,内存空间浪费
let person = {}
- 工厂模式创建
//工厂函数创建对象
let createPerson=(name,age)=>{
let p = {};
p.name = name;
p.age = age;
p.run = ()=>{console.log('run....')}
return p
}
let ww= createPerson('wwangwang',18)
let wc= createPerson('wangcai',18)
内置类
- Number
let n1 = 3.14653
n1.toFixed(2) // n1 不是对象, 但是在调用方法时,会被包装成一个对象,调用结束后,就还原成一个基本数据类型
- String
let s1 = 'ajax'
n1.toUpperCase() //s1 不是对象, 但是在调用方法时,会被包装成一个对象,调用结束后,就还原成一个基本数据类型
- Boolean
- Array
- Date
- Function
- Math 这个类不能new 单体内置类
- ...
一个DOM元素 本质就是一个对象,其上的属性非常多,操作这个对象,性能很低
类型判断
- typeof判断所有变量的类型,返回值有number、string、boolean、function、object、undefined。
- typeof对于丰富的对象实例,只能返回object,导致有时候得不到真实的数据类型。
- instanceof用来判断对象,代码形式(obj1 instanceof obj2)(判断obj1是否为obj2的实例),obj2必须为对象,否则会报错。返回的是布尔值。
- instanceof可以对不同的实例对象进行判断,判断方法是根据对象的原型链依次向下查询,如果obj2的原型属性存在于obj1的原型链上,(obj1 instanceof obj2)值为true。
instanceof 判断一个对象是否属于某个类
p instanceof Person
typeof 判断一个数据的类型 只能返回原始数据类型的值 函数和对象, 无法区分数组和对象
let arrList = [1,1.2,'ajax',undefined,null,NaN,false,[1,2,3],{name:'ajax'},function fn(){}]
arrList.map((item)=>{console.log(item+'的类型是'+ typeof(item))})
typeof
操作对象
CRDU 增删改查
- 通过打点来访问对象的属性
- 通过[]去获取对象的属性,有些情况只能通过[]来访问,比如for... in... 循环
let obj = {
name: 'ajax',
age: '18',
run:()=> { console.log(this) }
};
for (let key in obj) {
console.log(key)
console.log(obj[key]) //这里这个可以是变量
}
- 对象中的键是 字符串类型,没有添加引号也是字符串类型,也可以是数字obj[123]
- 对象没有length,所以不能使用for,用for..in
- 数组也可以使用对象的遍历方法
//遍历数组
let arr = ['ajax','alex','acex']
for (let k = 0; k < arr.length; k++) {
console.log(arr[k]);
}
arr.forEach(item => {
console.log(item);
});
for (const item of arr) {
console.log(item);
}
for (const key in arr) {
if (Object.hasOwnProperty.call(arr, key)) {
console.log(arr[key])
}
}
- delete obj.name
原型链
原型链关系图:
Function._ _ proto _ _ == Function.prototype