在js中,有2种编程思维
面向过程:
面向对象:
核心就是对象(类),对象的组成有2种 {"name":ls, skill:function(){console.log("敲代码")} }
属性:描述 静态的
方法:行为 动态的
面向对象三大特点
封装
继承
多态
1.1.1字面量创建
==缺点:创建单个==
var obj = {
"name": "zs",
"age": 23,
"skill": function () {
console.log("敲代码")
}
}
console.log(obj);
console.log(obj.age);//23
obj.skill(); //敲代码
1.1.2new关键字创建
==缺点:代码冗余==
1.1.3工厂模式创建
==缺点:类别识别不明确,代码冗余 浪费内存==
1.1.4构造函数创建
==缺点:浪费内存==
==如何创建构造函数==
构造函数的函数名首字母必须大写,为了和普通函数做区别
方法和属性是直接给this
必须使用new关键字进行调用 否则和普通函数没有区别
==new操作符做了什么==
隐式创建了一个空对象,让this指向这个空对象
执行构造函数中的代码
将实例化对象的__ proto __ 指向构造函数的prototype
隐式返回对象
1.1.5原型创建
==缺点:不能传参==
//创造构造函数
function Person(){}
// 将方法和属性添加到构造函数的prototype上 共享的属性和方法
console.dir(Person);
Person.prototype.name = "张三";
Person.prototype.age = 20;
Person.prototype.skill = function(){
console.log("敲代码")
}
console.dir(Person);
// 实例化对象
var res1 = new Person();
console.log(res1);//实例化对象的__proto__指向构造函数的prototype
console.log(res1.__proto__);
var res2 = new Person();
console.log(res2);
console.log(res2.__proto__);
1.1.6混合创建
构造函数创建(传参)+原型创建(不传参)
原型prototype:构造函数中用来存储共享的方法和属性的对象
原型属性 __ proto __ :让实例化对象的 proto__指向构造函数的prototype
// Array是js内部创建好的构造函数 console.dir(Array); // 实例化对象 实例化对象的__proto__指向构造函数的prototype var arr = new Array(1,2,3,4,5); console.log(arr); console.log(Array.prototype === arr.__proto__);//true console.dir(Array.prototype);//Array上共享的属性和方法 var arr = new Array(1,2,3,4,5); //arr的__proto__ 指向Array的prototype var arr1 = new Array(4,5,6,6);// arr1的__proto__指向Array的prototype
原型链:在创建构造函数和实例化对象的时候 自动形成一种查找关系
先查找自身的属性和方法 然后再找proto,再找构造函数 如果都找不到返回undefined
1.this的指向问题
在事件处理函数中 this指向当前触发事件的对象(标签)
在Object数据类型中的方法中 this指向所在方法的对象
在普通函数中 this指向window
在构造函数中 this指向实例化对象
2.如何改变this指向
call(this的新指向,参数1,参数2......) 参数是分开写的 用逗号分隔
apply(this的新指向,[参数1,参数2.....])
var obj = {
"name": "小红",
"age": 10,
"getName": function () {
console.log(this.name);
}
}
obj.getName();// 小红 this指向 obj
var obj1 = {
"name": "小明"
}
obj.getName.call(obj1);//this指向obj1 小明
function fun1() {
console.log(this)
}
fun1();//this指向window
fun1.call(document.documentElement);
fun1.call(1);//
fun1.call("123");//
function fun2(a, b) {
console.log(a, b, this);
}
fun2(100, 200);// 100 200 window
fun2.call(obj1, 100, 200);// 100 200 obj1:{name:"小明"}
// 详细检测数据类型
console.log(Object.prototype.toString.call("124"))
console.log(Object.prototype.toString.call(123))
console.log(Object.prototype.toString.call(true))
console.log(Object.prototype.toString.call(undefined))
console.log(Object.prototype.toString.call(null))
console.log(Object.prototype.toString.call({}))
console.log(Object.prototype.toString.call([]))
console.log(Object.prototype.toString.call(function () { }))
console.log(Object.prototype.toString.call(new Date()))
console.log(Object.prototype.toString.call(/\d/gi))
//instanceof 检测当前数据是否属于某个构造函数
function Person() {
this.name = "ls"
}
var res = new Person();
// 检测res是否由Person构造函数创建的
console.log(res instanceof Person);//true
// apply(this的新指向,[参数1,参数2......])
function fun3(a,b){
console.log(this,a,b)
}
fun3();//window
fun3.apply(obj1,[100,200]);// obj1 100 200
//利用Math.max和Math.min求数组中最大的值和最小的值
var arr = [100,80,120,60];
// Math.max(序列1,序列2.....)
var a = Math.max.apply("12344",arr);
console.log(a);
var a = Math.min.apply("123",arr);
console.log(a);