Javascript基础


下载安装运行环境:https://nodejs.cn/download/
编写helloworld,node.js:

console.log("Helloworld"); 

执行,在对应的目录下执行命令行

node ./main.js

变量

变量可以分为基本数据类型以及复制数据类型

基本数据类型直接存,复制数据类型存的是引用

基本数据类型:整数,小数,逻辑变量

console.log(1); // 整数
console.log(1.2); // 小数
console.log(true); // 逻辑true
console.log(false); // 逻辑false


var a; // 分配一个内存,基本数据,
a = 3.5;
console.log(a);

a = 4;
console.log(a);

a = true;
console.log(a);


var b = null; // 没有存放任何数据
console.log(b);

// 使用一个没有初始化的变量, undefine
var c;
console.log(c);


// 按照顺序存放一组元素,从0开始,1, 2, 。。。
// [], 定义了一个数组对象
c = []; 
console.log(c);

c = [1, 2, 3, 4]
console.log(c);

// 数组是根据索引来访问元素, 索引是从0开始的,  索引-->value
console.log(c[0]); // 第0个元素 1
console.log(c[1]); // 第1个元素 2
console.log(c[2]); // 第2个元素 3
console.log(c[3]); // 第3个元素 4

// 数组里面可以存放任何不同类型的元素
c = [1, 2.1, true, false, [0, 1, 2]];

// {}表示定义一个表,字典, key: -->value
var list_table = {};
list_table = {
	0: true,
	hello: 3,
}

// 访问已经存在的key --> value,
console.log(list_table.hello); 
console.log(list_table["hello"]); 
console.log(list_table["0"]);
list_table["blake"] = 33;
console.log(list_table);

// 定义一个变量,让它指向一个函数对象 
// function关键字, (参数1, 参数2) { 函数体}
var call_func = function (param1, param2) {
	console.log("Hello call func!!!!", param1, param2);
	return;
}

// 变量,或者是名称, 传递参数
call_func(3, 4);

// 函数的返回值,可以有返回值,可以没有返回值

call_func = function(param1) {
	return (param1); // 返回我们的数据
};

// 在外面可以使用变量来接收这个数据
var ret = call_func(4);
console.log(ret);


// 函数名称来定义一个函数,调用的时候可以使用函数名称
// 这个函数名称就是指的这个函数对象
// 这个函数名称,整个js文件里面有效果
// 函数定义,但不会执行,真正执行的是调用,
// 调用的时候,再跳到函数里面执行,执行完成后,在返回到调用函数的下一条指令,继续执行
function test_func_name() {
	console.log("test_func_name");
} 

// 函数调用
console.log("begin call func");
test_func_name();
console.log("out call func");

// 字符串对象; "Hello", 'Hello'
var hello_str = "Blake";
console.log(hello_str);


hello_str = 'Blake';
console.log(hello_str);

// 整数,小数,逻辑变量,  --->简单的数据对象, = 传的是值
// 字符串对象, 数组对象,表, 函数对象  = 传递的是引用, 变量"指向"哪个对象;

var b = 3;
var c = b; // 传递的是值,因为变量本身的内存就能存下基本数据类型;
c = 4;
console.log(b); // b = 3

// 复杂数据对象,我们变量里面存放的是引用,引用是可以直接存放到我们的变量所对应的内存里面的;
b = [1, 2, 3]; // 把数组的访问快捷方式,"引用"复制给变量b的内存
c = b; // 传递的不是值,而是引用,对象的地址,对象的快捷方式
c[0] = 2; // c[2, 2, 3]
console.log(b); // [1, 2, 3] ? [2, 2, 3]


// 变量保存了基本数据类型的值
// 变量保存了复杂数据对象的引用,----> 变量指向了这个复杂的数据对象,"访问的快捷方式", "对象所在的地址"
var System = {
	test_name: function() {
		console.log("test_name func");
	},

	test_func: function() {
		console.log("test_func func");
	},

	age: 10,
	sex: -1,
	name: "Blake",
};

// System变量 ---> 表对象,表对象有两个元素key, value
// 表.key-->value
System.test_name();
System.test_func();
console.log(System.name);

var  Cmd = [
	function() {
		var my_test = 10;
		console.log("helloworld");
	},
];

Cmd[0]();


// 函数重名,是我们很多错误的根源
var my_func = function() {};
/*
function test_func_call() {
	console.log("test_func_call");
}*/

test_func_call(); // 为什么在这里调用,调用的不是上一个的函数呢??

// 定义两个重名的函数
function test_func_call() {
	console.log("test_func_call copy");
}

// null, 主动,undefine, // 被动 

test_func_call();

var undefine_temp;
console.log(undefine_temp);


var a_ptr = {
	0: "Blake"
};

var b_ptr = {
	0: "Huangdong",
};

a_ptr = b_ptr;

模块

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

var utils = {
	random_int: function (start, end) {
		var num = start + (end - start) * Math.random();
		num = Math.floor(num);
		return num;
	}, 
};

module.exports = utils;

main.js
注意this的机制和bind的强制绑定

// 返回的是utils里面的module.exports
// 第一次执行,加载utils.js文件,然后并执行这个文件里面的js指令,返回module.exports;
// 如果不是第一次,直接返回module.export
// 指向的是module.exports指向的对象
var utils = require("./utils");

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


// this = ?
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);

// this 有什么用呢?

面向对象

  1. 注意new的机制其实是调用构造函数构造了一个表
  2. 每个函数都有prototype,这个prototype相当于一个元表,构造出来新表后拥有旧表的全部功能。prototype会被复制到新表的__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);
    
    var p2 = new person("xiaotian", 12);
    console.log(p2);
    
    
    p.test_func();
    p2.test_func();
    
    // new prototype 
    // 每一个函数对象,都会有一个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__里面搜索;
    
    // 定义个类
    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());
    
    

继承

  1. 需要定义一个新的funcion
  2. 用basefunction.Call(this)来继承数据成员
  3. 用funcion.prototype来继承成员函数
  4. 如果想要调用子类的函数func 可以用basefunction.prototype.func.call(this)
    // 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 
    通用继承方法Class的编写
    
    function Class(params) {
    	var new_class = function() { // 新类的构造函数
            if(params.extend){
                params.extend.call(this);
            }
            if(params.init){
                params.init.call(this);
            }
        };
    	// 继承基类的方法
    	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); 

文章作者: 微笑紫瞳星
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 微笑紫瞳星 !
  目录