代码模块与面向对象

一、代码模块

1、js里面代码可以放在不同的文件里,称为代码模块;
2、一个模块需要引用其它模块代码的时候使用 require;
3、 require:
(1) 如果是第一次调用,那么就加载,执行脚本;
(2) 每个代码模块由module.exports 导出的对象;
(3) 每次require的时候,都返回module.exports;
(4)如果不是第一次执行,那么直接返回module.exports;
utils.js

//定义一个表utils,表内定义一个函数random_int
var utils = {
    random_int: function (start, end) {
        var num = start + (end - start) * Math.random();
        num = Math.floor(num);
        return num;
    }, 
};

module.exports = utils;  //导出表utils,也可以直接到导出表中的函数

main.js

var utils = require("./utils");
console.log(utils);
var num = utils.random_int(10, 20);
console.log(num);

二、this

1、function.call(this, param1, param2);
2、表.函数名(参数):
(1) 函数里面有一个this对象,指的是外面的表;
(2) 如果外面没有表,那么this为undefine;
(3) 函数.bind(数据对象),会产生一个新的函数对象,调用该函数的this,就是外面bind的对象;

function test_func(name, sex) {
    this.name = name;
    this.sex = sex;
}
// this, 类是与一个参数一样的,显式传递this
// 函数对象.call(实例, 参数)
var xiaoming = {};
test_func.call(xiaoming, "xiaoming", 10);
console.log(xiaoming);
// 隐式传递this
var xiaohong = {
    name: "xiaohong",
    test_func: function() {
        console.log(this);
    },
    test_bind: function() {
        console.log(this);
    }.bind(4),
};
// 隐式的传递this,将xiaohong 作为this,传给该函数。
xiaohong.test_func();
xiaohong.test_bind();
// 强制传递this;
var func = function() {
    console.log(this);
}.bind(xiaohong);
func();
func = function() {
    console.log(this);
}
// bind是在原来的对象的基础上,产生了一个新的函数对象;强制bind this,优先级额比其它的都高;
func = func.bind(xiaohong);
func();
func.call(4);
// 强制bind > 显示 > 隐式
xiaohong.test_func.call(4);

三、new与构造函数

1、js 构造函数: 函数(参数),一般和类名一样;
2、new +构造(参数1, 参数2….);
(1)先创建一个{}对象;
(2)将这个新对象绑定到函数里面的this;
(3)构造函数对象的prototype 复制给新对象的 proto
(4) 返回新创建的对象;
3、表.函数调用搜索顺序,现在key, value里查找,再到proto里找;

function person(name, age) {
    this.name = name;
    this.age = age;
}
person.prototype.test_func = function() {
    console.log("person test_func called!!!!");
    console.log(this);
};
var p = new person("xiaohong", 10);
console.log(p);
p.test_func();

运行结果:
person { name: ‘xiaohong’, age: 10 }
person test_func called!!!!
person { name: ‘xiaohong’, age: 10 }

四、原型引用

1:每个函数对象都有prototype属性;
3: clone一个函数对象的prototype;
(1)定义一个空函数;
(2)空函数的prototype = 函数对象的prototype;
(3) 新构造函数.prototype = new 空函数();

// 每一个函数对象都有一个prototype变量,指向一个对象,
// 什么也没有就为{}
var func_temp = function() {
    console.log("func_temp####");
};
console.log(func_temp.prototype);
// end
// prototype是一个对象,所以可以扩充key: value;
func_temp.prototype.test_func = function() {
    console.log("test_func", this);
};
func_temp.prototype.test_func2 = function() {};
// step1 var a = {};
// step2 a __proto__: prototype 的浅复制;
// step3 实例 作为this,传递给后面的函数
// step4 调用这个函数;
var data = new func_temp();
// 两个表,但是里面的值一样;
console.log(data.__proto__);
console.log(func_temp.prototype);
// data is 表;
data.name = "XXXXXX"
data.__proto__.test_func();
// 把data, 作为this,传递给 data.__proto__对象里面的函数;
data.test_func(); // ---> data.__proto__.test_func.call(data);
data.__proto__.test_func.call(data);
data.test_func = function() {
    console.log("new test_func", this);
}
data.test_func(); 
// data.key_func, 首先会在实例的表里面搜索,有没有这样的key,如果没有,那么再到对象的__proto__里面搜索;

五、js实现继承

1、子类clone 基类构造函数的prototype;
2、子类和基类如果有同名的方法,会现在当前这个类的函数;
3、子类的实例显示的调用基类的函数
基类.prototype.函数名字.call(实例, 参数1,参数2);
4、编写一个Class()方法来定义一个类,让它继承基类;

// 定义个类
function Point() {
    this.xpos = 0;
    this.ypos = 0;
}
Point.prototype.set_pos = function(x, y) {
    this.xpos = x;
    this.ypos = y;
}
Point.prototype.get_ypos = function() {
    return this.ypos;
}
// end 
var p1 = new Point();
var p2 = new Point();
p1.set_pos(10, 10);
p2.set_pos(100, 100);
console.log(p1.get_ypos());
console.log(p2.get_ypos());
// js 继承
var Person = function() {};
Person.prototype.set_name = function(name) {
    this.name = name;
    console.log("set_name called");
};
Person.prototype.set_age = function(age) {
    this.age = age;
};
Person.prototype.test_func = function() {
    console.log("person test_func");
};
// 定义一个人;
var Man = function() {};
// Man.prototype();
// 做法(1)
// Man.prototype = Person.prototype; // ?可以吗?
// 在原来的基类的prototype做一次浅拷贝
var Super = function() {};
Super.prototype = Person.prototype;
Man.prototype = new Super();
Man.prototype.set_sex = function(sex) {
    this.sex = sex;
};
Man.prototype.test_func = function() {
    Person.prototype.test_func.call(this);
    console.log("Man test_func");
}
var m = new Man();
m.set_name("xiaoming");
m.set_age(10);
m.set_sex(0);
console.log(m);
m.test_func();
// end 
function Class(params) {
    var new_class = function() {};
    // 继承基类的方法
    if (params.extend) {
        var Super = function() {};
        Super.prototype = params.extend.prototype;
        new_class.prototype = new Super();
    }
    for(var key in params) {
        if (key == "extend") {
            continue;
        }
        new_class.prototype[key] = params[key];
    }
    return new_class;
}
var Student = Class({
    extend: Person,
    set_class: function(class_num) {
        this.class_num = class_num;
    },
    set_grade: function(grade) {
        this.grade =  grade;
    }
});
var s = new Student();
s.set_name("xiaohong");
s.set_class(10);
s.set_grade(2);
console.log(s);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值