分享一些上课时讲的内容:
1、给内置对象添加方法
var arr = new Array(1, 2, 3, 4);
arr.join('/');
console.dir(arr);
//若方法在实例对象没有找到,就去创建该实例对象的构造函数里的原型对象里找
//需求:我希望字符串里有一个倒序字符串的方法
String.prototype.myStr = function () {
for (var i = this.length - 1; i >= 0; i--) {
console.log(this[i]);
}
}
var sttr = 'abcdef';
sttr.myStr();
console.dir(String);
//可知这个方法添加到系统里面了
//需求:给字符串里添加一个打招呼的方法
String.prototype.hi = function () {
console.log(this+'你好啊');
}
var sttr2 = '小明';
sttr2.hi();
2、原型和原型链
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat = function () {
console.log('番茄鸡蛋');
}
var per = new Person('小明',20);
console.dir(per);
console.dir(Person)
//原型链:一种关系,是实例对象和原型对象之间的关系,是通过_proto_原型来联系的
这里面可以通过控制台观察其关系
3、原型的指向是否可以改变
function Person() {
}
Person.prototype.eat = function () {
console.log('人的吃');
}
function Student() {
}
Student.prototype.play = function () {
console.log('学生的玩');
}
//想让他们有关系-->把学生的指向改变到人的对象
Student.prototype = new Person();
var stu = new Student();
stu.eat();
//所以原型对象的指向是可以改变的
4、指向发生变化后添加属性和方法
function Person() {
}
Person.prototype.eat = function () {
console.log('人的吃');
}
function Student() {
}
Student.prototype.play = function () {
console.log('学生的玩');
}
//想让他们有关系-->把学生的指向改变到人的对象
Student.prototype = new Person();
Student.prototype.study = function(){
console.log('我要每天敲代码');
}
var stu = new Student();
stu.eat();
stu.study();
//所以原型对象的指向是可以改变的
5、原型最终指向了哪里
function Person() {
}
Person.prototype.eat = function () {
console.log('人的吃');
}
var Per = new Person();
console.dir(Per);
console.dir(Person);
//实例对象有_proto_属性
//构造函数有prototype属性-->也是原型对象
//原型对象有_proto_属性
//console.log(Person.prototype.__proto__);//输出Object
console.log(Object.prototype.__proto__);//null
6、神奇的原型链
var div = document.getElementById('div');
console.dir(div);
在控制台中观察相关的属性
7、继承
/*
* 面向对象编程思想:万物皆对象,根据需求找对象,分析对象,找对象有什么特征和行为,再创建对象
* 特征:封装 继承 多态
* 封装:包装 重复的代码存到函数里
* 继承:也是一种关系,是类与类的关系,js里没有类,js里有构造函数里面的原型对象,通过原型对象来实现继承
* 目的:数据共享,节省内存
* 什么样关系:是父类与子类的关系
* 有一个人类:有性别 年龄 吃饭 睡觉
* 学生:姓名 性别 年龄 吃饭 睡觉 学习
* 程序员:姓名 性别 年龄 吃饭 睡觉 敲代码
* */
function Person(name,sex,age) {
this.name = name;
this.sex = sex;
this.age = age;
}
Person.prototype.eat = function () {
console.log("人在吃饭");
}
function Student() {
}
//改变原型对象的指向
Student.prototype = new Person('Ming',18,'male');
var stu = new Student();
console.log(stu.name);
console.log(stu.age);
console.log(stu.sex);
stu.eat();
8、继承案例
//动物:名字 体重 吃东西
//小狗:名字 体重 吃东西 汪汪叫
//柯基:名字 体重 吃东西 汪汪叫 睡觉
function Animal(name,weight) {
this.name = name;
this.weight = weight;
}
Animal.prototype.eat = function () {
console.log('吃东西');
}
function Dog() {
}
Dog.prototype = new Animal('doge','10kg');
Dog.prototype.bark = function () {
console.log('汪!');
}
function Corgi() {
}
Corgi.prototype = new Dog();
Corgi.prototype.sleep = function () {
console.log('zzz');
}
var corgi = new Corgi()
console.log(corgi.name);
console.log(corgi.weight);
corgi.eat();
corgi.bark();
corgi.sleep();
9、借用构造函数
function Animal(name,weight) {
this.name = name;
this.weight = weight;
}
Animal.prototype.eat = function () {
console.log('吃东西');
}
function Dog(name,weight) {
Animal.call(this,name,weight);
//call方法就是把dog里面的属性指向指向到Animal狗仔函数里
}
var dog1 = new Dog('中华田园犬','50kg');
console.log(dog1.name,dog1.weight);
var dog2 = new Dog('电动小马达','10kg');
console.log(dog1.name,dog1.weight);
dog2.eat();//报错
//说明call方法解决继承属性,但是又有缺陷,不能继承父类的方法
10、组合继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat = function () {
console.log('人吃的东西');
}
function Student(name, age, score) {
Person.call(this,name,age);
this.score = score;
}
Student.prototype = new Person();
Student.prototype.study = function () {
console.log('敲代码');
}
var stu1 = new Student('Ming',20,100);
console.log(stu1.name,stu1.age,stu1.score);
stu1.eat();
stu1.study()
//通过改变this指向继承了人的属性和方法
11、拷贝继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat = function () {
console.log('人吃的东西');
}
function Student(name, age, score) {
Person.call(this,name,age);
this.score = score;
}
Student.prototype = new Person();
Student.prototype.study = function () {
console.log('敲代码');
}
var stu1 = new Student('Ming',20,100);
console.log(stu1.name,stu1.age,stu1.score);
stu1.eat();
stu1.study()
//通过改变this指向继承了人的属性和方法
12、函数的角色
//函数的角色
/*//1.有名函数-->函数的声明
function f1() {
console.log('我·函数');
}
f1();
//2.匿名函数-->函数的表达式
var f2 = function () {
console.log('我·也是函数');
}
f2();*/
if(true){
function f1() {
console.log('我·吃饭!');
}
}else {
function f1() {
console.log('我·不吃饭!');
}
}
f1();
var f2;
if(true){
f2 = function () {
console.log('我·吃饭!');
}
}else {
f2 = function () {
console.log('我·不吃饭!');
}
}
f2();
//如果用if else 用函数声明 ie8会默认走false
//所以以后尽量用函数表达式
13、函数中this的指向
/*
* 普通函数的this指的是谁-->window
* 构造函数中this指的是谁-->实例对象
* 原型对象中的属性和方法中的this指的是谁-->当前的实例对象
* 定时器的this指向的是谁-->window对象
* */
function f1() {
console.log(this);
}
f1();
function Person() {
console.log(this)
}
Person.prototype.eat = function () {
console.log('吃!')
}
var per = new Person();
console.log(per);
per.eat();
14、函数也是对象
//函数也是对象 对象不一定是函数
//对象里有一个__proto__属性,也是对象
//构造函数里有prototype属性,也是对象
function f1() {
}
f1();
console.dir(f1);//f1既是函数,也是对象
console.log(Math);//Math对象不是一个函数
15、在数组中调用函数
//数组里面可以储存任何类型的数据-->也可以储存函数
var arr = [
function () {
console.log('乌拉');
},
function () {
console.log('噢啦');
}
]
//遍历数组里面的函数叫回调函数->把函数当做参数来使用
arr.forEach(function (ele) {
ele();
})