Js基础总结三
程序员文章站
2022-06-30 20:49:44
...
面向对象的JavaScript
总结一下,有这么几条规则需要遵守:
- 不要使用new Number()、new Boolean()、new String()创建包装对象;
- 用parseInt()或parseFloat()来转换任意类型到number;
- 用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
- 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {…};
- typeof操作符可以判断出number、boolean、string、function和undefined;
- 判断Array要使用Array.isArray(arr);
- 判断null请使用myVar === null;
- 判断某个全局变量是否存在用typeof window.myVar === ‘undefined’;
- 函数内部判断某个变量是否存在用typeof myVar === ‘undefined’。
- 任何对象都有toString()方法吗?null和undefined就没有!确实如此,这两个特殊值要除外,虽然null还伪装成了object类型。
- number对象调用toString()报SyntaxError:
date 的一系列方法
var now = new Date();
console.log(now);
now; // Thu Jan 10 2019 16:06:12 GMT+0800 (中国标准时间)
now.getFullYear(); // 2019, 年份
now.getMonth(); // 0, 月份,注意月份范围是0~11,0表示一月
now.getDate(); // 10, 表示10号
now.getDay(); // Thu, 表示星期四
now.getHours(); // 16, 24小时制
now.getMinutes(); // 51, 分钟
now.getSeconds(); // 20, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1547107650170, 以number形式表示的时间戳
正则表达式
//测试一下11位手机号
var reg1 = /^(135|180|138)\d{8}$/;
var p1 = '13577031234';
var p2 = 18099456789;
var p3 = 13746547897;
console.log("test reg");
console.log("正则表达:"+reg1);
console.log(reg1.test(p1)+" "+reg1.test(p2)+" "+reg1.test(p3));
console.log(reg1.exec(p1));
var email = '[email protected]';
var eamil1 = '[email protected]';//'bill%[email protected]' [email protected]
var reg2 = /^\w+(\.?\w+)*@\w+(\.com|\.org)$/;
console.log(reg2.test(email)+" eamil1:"+reg2.test(eamil1)+" "+reg2.test('bill%[email protected]'));
var email2 = '<Tom Paris> [email protected]';
var reg3 = /\<(\w+)\s+\w+\>\s+(\w+)@\w+\.\w+/;
//当有 () 时,即分组, 使用 regexp.exec(),会得到分组匹配成功的内容
var r = reg3.exec(email2);
var r1 = reg3.exec(email2);
var r2 = reg3.exec(email2);
console.log(reg3.test(email2));
console.log(r.toString()+" "+r1+" "+r2);
JSON对象
JSON.stringify(object)–>变为json格式
JSON.stringify(object,function(key,vlaue){…},‘分割符’)–>第二种方式 带多参数,并且可以加工object
例子:
var ffewi = {
name:'ffewi',
habit:'java',
//arr:[1,2,3]
};
console.log(ffewi);//输出的是对象
var json = JSON.stringify(ffewi);//默认转换 {"name":"ffewi","habit":"java"}
console.log(json);
//设置下转换 后的分割格式
var json1 = JSON.stringify(ffewi,null,"|");//输出会带有"\n|"(换行|)的格式
console.log(json1);
//通过 指定参数
var json2 = JSON.stringify(ffewi,['name'],' ');
console.log(json2);
//使用加工方法
var json3 = JSON.stringify(ffewi,conver,' ');
function conver(key,value){
console.log(typeof(key)+": "+key+": "+value);
//console.log("value:"+value.name);
for(var k in value){
//console.log(k);
//console.log(value[k]);
if(k=='name'){value[k]='hello '+value[k]}
if (k=='habit'){value[k] = 'thinking in '+value[k]}
}
return value;
}
console.log(json3);
//解析 json-->object
var ob = JSON.parse('{"name":"ffewi","age":23,"time":2016}');
console.log(ob.name+" "+ ob.age + " "+ ob.time);
//解析时也可以附加加工函数
// JSON.parse(str,function());
var ob1 = JSON.parse('{"name":"ffewi","age":23,"time":2016}',addtime);
function addtime(key,value){
//console.log(key); 这个key 不晓得是传的什么
//console.log(value); 这个是对象所有属性及属性值
/*if (value.time!=null) {
value.time += "-7-21";
}*/
if (key==='time') {
value.time += "-7-21";
}
return value;
}
console.log(ob1.name+" "+ ob1.age + " "+ ob1.time);
//key还真的有用 我还一直以为是""
var example = JSON.parse('{"name":"小明","age":14}', function (key, value) {
// 把number * 2:
if (key === 'name') {
console.log(key);
return value + '同学';
}
if(key=='age'){console.log(key)}
return value;
});
console.log(example.name+" "+ example.age);
继承
JavaScript中的面向对象结构
- 通过
__proto__
= object 继承关系 (prototype) - object=Object.create(object)
定义一个class 通过 __proto__ 方式
var people = {
//属性
name:'undifined',//默认值
power:99,
//方法:
walk:function(){
console.log(this.name+": is running");
}
}
定义一个我
var my = {
//name:'ffewi'
};
my.name = 'ffewi';
my.__proto__ =people;
my.walk();//结果看出来我在跑
通过 Object.create(object) 的方式
定义父类
var par = {
name:'kiki',
fly:function(){
console.log(this.name+" is flying!");
}
}
function createOb(name){
var s = Object.create(par);
s.name=name;
return s;
}
实例化
var ss = createOb('ffewi');
ss.fly();
创建对象
创建对象 相似与java new Object()
定义构造函数
function People(name){
//property
this.name = name;
//method
this.hello = function(){
console.log("hello : "+this.name);
}
}
通过new 实例一个对象
var my = new People('ffewi');
my.hello();
//上面看起来 就是一个函数,但是 如果不用 new 创建出来的不是一个对象模型
var error1 = People('error');
//error1.hello(); 会发现 方法里面的 this 指向 undefined
var my1 = new People('tang');
my1.hello();
//两个对象 hello方法是否一个对象里面的?
console.log(my.hello==my1.hello);//false 不是一个对象模型里面的方法
上面的构造方法 需优化, 因为每次都要new 防止忘记new 可以封装方法
并且 上面的构造方法,每次new 一个对象 hello方法 都会开辟的是另一块空间,浪费内存 待优化 如下:
//定义的对象模型
function Evil(obj){
this.name = obj.name||'tang';//默认值:tang
}
//将每个实例对象的方法 托付给 向上的父类 一样
Evil.prototype.destroy = function(){
console.log(this.name+" destroy everything!");
}
//定义一个new 对象的方法
function createEvil(obj){
return new Evil(obj||{});//可以传入对象,或者默认为一个空对象
}
var e1 = createEvil({name:'ffewi'});
e1.destroy();
var e2 = createEvil();//不传对象属性时,默认空对象-->{}
e2.destroy();
//看看e1 e2 的 destroy 是否同一个方法
console.log(e1.destroy==e2.destroy);//true 表名方法 为同一方法,优化了 开销
原型继承
原型继承 什么个概念?
就是 父类 People–>centerObject–>Object
但是,如果用People.prototype=centerObject.prototype; 结果是People直接指向了Object这里需要一个中间 空函数 做过度
example :
继承关系为: primaryStudent–>Student–>Object–>null
function Student(ob){
this.name = ob.name||'ffewi';
this.hello = function(){
console.log("super");
}
}
function PrimaryStudent(ob){
Student.call(this,ob);
this.grade = ob.grade||1;
}
var ps = new PrimaryStudent({name:'xiaoming',grade:100});
console.log(ps instanceof PrimaryStudent);//true
console.log(ps instanceof Student);//false 希望的是 ps即时 student 也是primaryStudent
//这个看着属性和内容都是继承了的,但是 原型指向却不正确
console.log(ps.name+" "+ps.grade);
ps.hello();
所以 上面的指向链为 new ob() --> PrimaryStudeng–> -->Object --> null
修改 应是: new ob() --> PrimaryStudeng–> Student -->Object --> null
一层一层原型继承关系 中间空函数 过度
步骤 3步
//原型:Student1
function Student1(props){
this.name = props.name||'ffewi';
this.hello = function(){
console.log("super");
}
}
//子类
function PrimaryStudent1(props){
Student.call(this,props);
this.grade = props.grade||1;
}
//定义空函数
var F1= function(){
}
//函数原型指向Student
F1.prototype = Student1.prototye;
console.log("F.prototype=:"+(F1.prototype === Student1.prototye));
PrimaryStudent1.prototype = new F1();
PrimaryStudent1.prototype.constructor = PrimaryStudent1;
PrimaryStudent1.prototype.getGrade = function () {
return this.grade;
}
var ps1 = new PrimaryStudent1({
name:'hong',
grade:2
});
console.log(ps1.name+ " " + ps1.grade);
console.log(" primary:" +(ps1 instanceof PrimaryStudent1));
console.log(ps1 instanceof Student1);
console.log(ps1.__proto__ === PrimaryStudent1.prototype);
console.log(ps1.__proto__.__proto__ === Student1.prototype);
//看看封装
function inherits(Child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
function Student2(props) {
this.name = props.name || 'Unnamed';
}
Student2.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
function PrimaryStudent2(props) {
Student.call(this, props);
this.grade = props.grade || 1;
}
// 实现原型继承链:
inherits(PrimaryStudent2, Student2);
// 绑定其他方法到PrimaryStudent原型:
PrimaryStudent2.prototype.getGrade = function () {
return this.grade;
};
var tang = new PrimaryStudent2({
name:'xiangfang',
grade:3
});
console.log(tang.name+","+tang.grade);
console.log((tang instanceof PrimaryStudent2)+"分开"+(tang instanceof Student2));
//tang的以及原型是 PrimaryStudent 向上是 Student
console.log((tang.__proto__===PrimaryStudent2.prototype));
console.log(tang.__proto__.__proto__===Student2.prototype);//true;
练习继承
//原型
function S1(o){
this.name = o.name||'NoName';
// console.log(o.name);
}
S1.prototype.hello = function(){
console.log("hello:"+this.name);
}
//子类
function Sub(o){
S1.call(this,o);
this.age = o.age;
}
//指定链接链
var F = function(){};
F.prototype = S1.prototype;
Sub.prototype = new F();
Sub.prototype.constructor = Sub;
Sub.prototype.getAge = function(){
return this.age;
};
var xiaoming = new Sub({
name:"xiaoming",
age:23
});
console.log(xiaoming.name +" "+ xiaoming.age+" getAge:"+xiaoming.getAge());
xiaoming.hello();
console.log("xiaoming both S1 and Sub :"+(xiaoming instanceof S1)+(xiaoming instanceof Sub));
//xiaoming的原型是Sub
var s1 = (xiaoming.__proto__ === Sub.prototype);
//再向上是S1
var s2 = (xiaoming.__proto__ .__proto__ === S1.prototype);
console.log("s1:"+s1+" s2:"+s2);
class / extends
直接使用class
和 extends
关键字轻松替换上面的继承关系链。
几乎和java类构造相差无几。
class Father{
//构造方法
constructor(name){
this.name =name||'wuming';
}
//方法
hello(){
console.log("hello: "+this.name);
}
}
//父类实例
var f = new Father();
f.hello();
//子类继承
class Sub extends Father{
constructor(name,like){
//调用父类构造
super(name);
this.like = like;
}
}
//子类实例
var s = new Sub('keke','php');
s.hello();
console.log(s.like);
//简直就和java一样。。
console.log("s is Sub and Father Type:"+(s instanceof Sub)+" and "+(s instanceof Father));
console.log("s'prototype is Sub and s'prototype'prototype is Father Type:"+(s.__proto__ === Sub.prototype)+" and "+(s.__proto__.__proto__ === Father.prototype));