代码模块与面向对象

来源:互联网 发布:北京人口数据统计 编辑:程序博客网 时间:2024/06/05 08:20

一、代码模块

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

//定义一个表utils,表内定义一个函数random_intvar 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);// 隐式传递thisvar 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);