构造函数
- 用 new 关键字来调用的函数叫做构造函数;首字母一般大写。
- 是一个特殊函数,主要用来初始化对象(为对象变量赋初始值);
- 这样我们就可以通过一个构造函数创建多个对象,这些对象拥有相同的构造,都可以使用这个构造函数的方法和属性。
function Person(name, age) {
console.log(this)
this.name = name;
this.age = age;
}
原型和原型链
js中万物皆对象;
- 对象又分为普通对象(Object)和函数对象(Function)
- 任何对象都具有隐式原型属性(
__proto__),只有函数对象有显式原型属性(prototype)。
基本类型
undefined、null、Boolean、number、String、symbol(防止属性名的冲突;用法:let sy = Symbol("KK");)
引用类型
统称为object类型,细分的话有:Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型 等。
原型
- 所有引用类型都有一个
__proto__(隐式原型)属性,属性值是一个普通的对象 - 所有函数都有一个
prototype(原型)属性,属性值是一个普通的对象 - 所有引用类型的
__proto__属性指向它构造函数的prototype
function proto() {
let a = [1, 2, 3];
console.log(a.__proto__ === Array.prototype)//true
}
proto()
原型链
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找(即它的构造函数的prototype),如果还没有找到就会再在构造函数的prototype的__proto__中查找(即构造函数.prototype.__proto__),这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
function Parent(month){
this.month = month;
}
var child = new Parent('Ann');
console.log(child.month); // Ann
console.log(child.father); // undefined
在child中查找某个属性时,会执行下面步骤:
访问链路为:
- 一直往上层查找,直到到null还没有找到,则返回undefined
Object.prototype.__proto__=== null- 所有从原型或更高级原型中的得到、执行的方法,其中的this在执行时,指向当前这个触发事件执行的对象
继承
原型继承
构造函数继承
回调函数
立即执行函数
js中函数的两种命名方式,即表达式和声明式。
- 函数的声明式写法为:function foo(){ }
这种写法会导致函数提升,所有function关键字都会被解释器优先编译,不管是声明在什么位置,都可以调用它,但是它本身不会被执行,定义只是让解释器知道其存在,只有在被调用的时候才会执行
- 函数的表达式写法为:var foo=function(){ }
这种写法不会导致函数提升,于是就必须先声明,再调用,否则会出错
(function () {}())
(function () {})()
浅克隆、深克隆
function clone() {
console.log('------------------clone-------------------')
// Object.assign实现浅拷贝
let a = { age: 1 }
let b = Object.assign({}, a);// Object.assign只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。
a.age = 2
console.log(b.age, 'Object.assign实现浅拷贝')//1
// 展开运算符...来实现浅拷贝
let c = { ...a }
a.age = 3
console.log(c.age, '运算符...来实现浅拷贝')//1
//深克隆(浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,使用深拷贝)
let deepObj = { name: 1, age: { num: 999, sex: undefined } }
let clone = { ...deepObj }
deepObj.age.num = 888
console.log(clone.age, '浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,使用深拷贝')//888
let deepObjaaa = { name: 1, age: { num: 999, sex: undefined } }
let jsonDeepClone = JSON.parse(JSON.stringify(deepObjaaa))
deepObjaaa.age.num = 888
// 会忽略undefined
// 会忽略symbol
// 不能序列化函数
// 不能解决循环引用的对象
console.log(jsonDeepClone.age, '通常可以通过JSON.parse(JSON.stringify(object))来解决')//999
console.log('------------------clone-------------------')
}
clone()
数组去重
function arrFn() {
console.log('------------------unique-------------------')
let arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false,
undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}, { a: 1 }, { a: 1 }];
// set去重 不会过滤对象
// let arrSet = Array.from(new Set(arr)) 和arrSet1一样
// console.log(arrSet, 'set去重')
let arrSet1 = [...new Set(arr)]
console.log(arrSet1, 'set去重')
// for循环去重
let arrcopy = [...arr]
for (let i = 0; i < arrcopy.length; i++) {
for (let j = i + 1; j < arrcopy.length; j++) {
if (arrcopy[i] === arrcopy[j]) {
arrcopy.splice(j, 1);
j--
}
}
}
console.log(arrcopy, 'for循环去重')
console.log('------------------unique-------------------')
}
arrFn()