1. JS构造函数
JS构造函数首字母大写(不成文的规定), 普通函数一般首字母小写
// 普通(用它new不规范)
function fn1() {
console.log('这是一个普通函数')
}
// 构造函数
function Person() {
// new
// 内部会声明一个var this = {};
// 函数体
// return this;
// 1.非严格模式下 this是window
// 2.严格模式下 this是undefined
// "use strict";
// 3. new的时候就是当前函数的实例
console.log(this.constructor === Person);;// new的时候都是true
console.log(this.constructor === arguments.callee);// new的时候都是true
console.log(this instanceof arguments.callee);// new的时候都是true
// invoke执行函数体内的代码
this.name = 'Green';
return '调用的返回值';
}
构造函数可以和普通函数一样被调用
var invoke = Person();
console.log(invoke);// 调用的返回值
构造函数还可以创建一个实例
// 创建一个实例 做构造函数
var instance = new Person();
console.log(instance);
2. 原型:可以供所有实例访问
function Animal(name) {
// this
this.name = name;
// V1:N个对象 N个相同方法赋值给N个属性
this.eat = function () {
console.log('哇呜哇呜..好吃')
}
}
var an1 = new Animal('小红');
an1.eat(); //哇呜哇呜..好吃
console.log(an1.name) // 小红
var an2 = new Animal('张三');
an2.eat(); //哇呜哇呜..好吃
console.log(an2.name)// 张三
1) 隐式原型 实例.proto
2) 显示原型 构造函数.prototype
Animal.prototype.age = 123;
Animal.prototype.eat = function(){
console.log(this.name,'正在哇呜哇呜..好吃')
}
console.log(Animal.prototype === an2.__proto__) //true
console.log(Animal.prototype === an1.__proto__) //true
console.log(an1.__proto__ === an2.__proto__) //true
3. 原型属性区分
var log = console.log;
function Animal(name) {
this.name = name;
}
// 数据共享
Animal.prototype.age = 123;
var an1 = new Animal('小K');
1)通用属性判断 无法区分 是否原型属性 或者实例自身属性
log('name' in an1); // true
log('age' in an1);// true
- 遍历 可以获取到所有的 无法区分 是否原型属性 或者实例自身属性
for (var key in an1) {
console.log(key, an1[key]);
}
3)hasOwnProperty() 非原型获取 判断是否属于自身属性
log(an1.hasOwnProperty('name')); // true
log(an1.hasOwnProperty('age')); // false
4)获取 key 获取value 【自身, 无法获取原型上的属性】
log(Object.keys(an1)); // [name]
log(Object.values(an1));
4. this指向 谁.调用的方法,this就代表谁
function fn(expressStr) {
console.log('exp:', expressStr, 'this:', this);
}
var arr = [fn,2,3];
arr[0]('arr[0]'); //this指向arr, arr[0]可以理解为: arr.0 取到了函数(),所以this代表数组
var obj = { fn: fn };
obj.fn('obj.fn');//this指向obj
var obj3 = {
fn: fn
}
var arrOfObj = [1, 2, 3, obj3]
arrOfObj[3].fn('arrOfObj[3]');
5. 改变this指向
var str = false;
function ffn(){
console.log('this:',this,'arguments:',arguments);
}
1)apply 调用的时候,使用第一个参数作为this
ffn.apply(str,[6,5,8])
2)call 调用的时候,使用第一个参数作为this,与call的区别是后面传递参数格式不同
ffn.call(str,1,2,3)
apply和call都是临时改变this指向
3)bind 返回一个改变了this指向的函数,也可以提前传递参数(this指向永久改变)
var newFn = ffn.bind(str,97)
newFn(98,99)// 新的函数还可以继续传递参数
注意:箭头函数不能用apply、call或者bind改变this指向
var arrows = () => { console.log(this, '箭头函数this') }
arrows(); // window
arrows.call(str, 'xxxx'); // window(不可改)