(一)原型
1.创建对象
自定义构造函数
function 构造函数名(参数...){
this.key = value;
.......
}
命名规范:
构造函数名首字母要大写 帕斯卡(每个单词首字母大写) 驼峰(从第二个单词开始首字母大写)。
new关键字创建对象
var 对象名 = new 构造函数名(实参...);
构造函数和普通函数:
- 相同点
- 都是函数
- 不同点
- 构造函数通过new关键字调用
- 普通函数直接调用
2.实例对象和原型
原型就是一个对象,原型一直都在。
1)获取原型语法:
构造函数名.prototype
2)原型作用:
节省内存。 因为原型中存放的成员(属性或方法),都可以被相关的构造函数所创建的对象共享。
3)找原型:
首先,会从对象本身中去找;
若对象中,找不到,则会通过__proto__
所提供的原型地址,找原型;
去原型中查找。
代码举栗:
// 学生类→ 构造函数
function Student(name, age, gender) {
// 属性
this.name = name;
this.age = age;
this.gender = gender;
// this.type = '学生'
}
// 获取原型
// 每一个函数都有一个对应的原型
var yx = Student.prototype;
// 对象.key = value
// 方法
yx.sayHi = function () {
// 方法内部:this 代表的是调用方法的对象
console.log('我叫什么' + this.name)
};
yx.writeCode = function () {
console.log('我会写code');
}
yx.type = '学生';
// 创建对象
var zs = new Student('张三', 10, '男');
// 创建对象
var ls = new Student('李四', 11, '男');
// 创建对象
var ww = new Student('王五', 17, '女');
(二)原型继承
原型继承实现时必会有下面两句代码:
- 先更改子类的原型prototype指向一个new 父类() 对象。
- 子类.prototype = new 父类();
- 再给子类的原型设置一个constructor指向子类
- 子类.prototype.constructor = 子类
// 用于设置原型
Employee.prototype = new Person()
// 设置原型的构造器
Employee.prototype.constructor=Employee
代码举栗:
// 人类 → 父类
function Person() {
this.name = '名字';
this.age = 10;
this.gender = '男';
}
Person.prototype.sayHi = function () { console.log('你好'); };
Person.prototype.eat = function () { console.log('我会吃。。。'); };
Person.prototype.play = function () { console.log('我会玩'); };
// 学生类 → 子类
function Student() {
this.stuId = 1000;
}
// 子类的原型prototyp指向父类的一个实例对象
Student.prototype = new Person();
// 添加一个constructor成员
Student.prototype.constructor = Student;
// 如何实现原型继承:
// 给子类的原型prototype重新赋值为父类的一个实例对象。
// 利用了原型链上属性或方法的查找规则。
// 创建一个学生对象
var stu1 = new Student();
console.log(stu1.constructor)
(三)借用继承
1.call方法
- 语法:函数名.call(调用者,函数实参,函数的实参...);
- 作用:该函数会立即执行,函数体内的this在被call时,this指向调用者。
2.用call方法实现继承
// 人类 → 父类
function Person(name,age,gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.sayHi = function () { console.log('你好'); };
Person.prototype.eat = function () { console.log('我会吃。。。'); };
Person.prototype.play = function () { console.log('我会玩'); };
// 学生类 → 子类
function Student(name,age,gender,stuId) {
// this关键字代表谁,代表的是一个学生对象,当前创建的对象 stu1 ,stu2
// var obj = this;
//【借用继承】
// Person.call(obj,name,age,gender);
Person.call(this,name,age,gender);
this.stuId = stuId;
}
// 创建第一个学生对象
var stu1 = new Student('张三',10,'男',10086);
// 创建第二个学生对象
var stu2 = new Student('李四',11,'女',10010);
(四)组合继承
// 人类 → 父类
function Person(name,age,gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.sayHi = function () { console.log('你好'); };
Person.prototype.eat = function () { console.log('我会吃。。。'); };
Person.prototype.play = function () { console.log('我会玩'); };
// 学生类 → 子类
function Student(name,age,gender,stuId) {
//【借用继承】
Person.call(this,name,age,gender);
this.stuId = stuId;
}
// 【原型继承】
Student.prototype = new Person();
Student.prototype.constructor = Student;
// 创建第一个学生对象
var stu1 = new Student('张三',10,'男',10086);
// 创建第二个学生对象
var stu2 = new Student('李四',11,'女',10010);
(五)函数内部this指向情况总结
1.普通函数中的this
普通函数内部的this指向window
function fn() {
console.log(this); //window
}
fn();
直接调用的函数就是普通函数
var obj = {
getSum: function () {
console.log(this); //执行obj。输出obj
function fn2() {
console.log(this); //window
}
}
};
obj.getSum();
2.定时器中的this
只要用到定时器,setTimeout和setInerval都默认指向window
。
3.构造函数
this指向当前创建的对象
。
//匿名函数一般首字母大写
function Person() {
this.name = 'zhang';
this.age = 10;
console.log(this); //Person{}
}
new Person();
4.对象的方法
this指向调用者
。
5.事件处理程序
this默认指向事件源
document.onclick = function () {
console.log(this); //document
}
(六)改变this的指向
1.call方法
- 语法:函数名.call(调用者,参数1,参数2...);
- 作用:函数被借用时会立即执行,并且函数体内的this会指向借用者或调用者
函数内部this指向谁,看函数在这一次的调用情况。
function fn(a, b) {
this.name = a;
this.age = b;
}
fn(10, 20); //指向window,window中增加name和age
var obj = {};
fn.call(obj, 'zhang', 10); //obj中增加name和age,仅在这一次增加
2.apply方法
- 语法:函数名.apply(调用者,参数1,参数2...);
- 作用:函数被借用时,会立即执行,并且函数体内的this会指向借用者或调用者
function fn(name, age) {
this.name = name;
this.age = age;
}
// 对象字面量
var obj = {};
fn.apply(obj, ['李四', 11]);
3.bind方法
- 语法:函数名.bind(调用者,参数1,参数2...);
- 作用:该函数被借用时,不会立即执行,而是返回一个新的函数,需要自己手动调用新函数
function fn(name, age) {
this.name = name;
this.age = age;
}
// 对象字面量
var obj = {};
fn.bind(obj, '李四', 11);
(七)函数作为函数的参数
- 把一个函数B当做实参,传递给另一个函数的A的形参,并在函数A内部调用
实参可以是任何类型的数据。(数字、字符串、布尔值、数组、对象、函数、undefined)。
函数也是一种数据类型,格式是function
。
网友评论