Javascript-基础知识(3)

 1.回顾:上篇学习了 正则,函数,作用域,日期函数

 2.这篇将学习,面向对象与原型,匿名函数和闭包,BOM


 3.面向对象与原型

  • 两种开发模式:1.函数式(过程化) 2.面向对象(oop):具有类的概念
  • JavaScript(ECMAScript)没有类的概念,因此他的对象也与基于类的语言中的对象有所不同。
  • 继承是通过原型或者对象冒充的形式进行的。
  • 1.创建对象,解决多个类似对象的创建,而使用工厂模式创建
  • e.g 工厂模式创建:
    function createObject(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.run=function(){
    return this.name+this.age;
    };
    return obj;
    }
    
    var box1=createObject('yuan',23);
    var box2=createObject('ming',243);


  • 2.构造函数 创建对象;this 相当于obj,没有return语句,他是自动返回的!
  • e.g
    function box(name,age){
    this.name=name;
    this.age=age;
    this.run=function(){
    return this.name+this.age;
    };
    }
    var box1=new box('yuan',23);
    var box2=new box('ming',243);


  • 构造函数也是函数,但函数名第一个字母必须大写
    必须new构造函数名,必须使用new 运算符!
  • 3.对象冒充的方式调用: call()和apply() 的使用,上面!
  • e.g
    var box3=new Object();
    box.call(box3,'zhuo',2122);
    shu(box3.run());


  • 4.原型 (prototype)
  • 用途:是包含可以由特点类型的所有实例共享的属性和方法。
    prototype 通过调用构造函数而创建的那个对象的原对象!
    如果是用原型的方式的话,地址是共享的。
  • e.g
    //原型
    function Box1(){} //构造函数体内什么都没有(实例属性和实例方法)
    Box1.prototype.name='yuan';
    Box1.prototype.age=12;
    Box1.prototype.run=function (){
    return this.name+this.age;
    };
    var box2=new Box1();
    shu(box2.run());


  • isPrototypeOf() :判断一个对象实例(对象引用)是不是指向了原型对象,基本上,只要实例化了,就是指向了!
  • 原型执行流程: 1,先查找函数实例里面的属性或方法,有,则返回 2,在查找原型中有没有属性和方法
  • hasOwnProperty(属性名) :判断实例中是否含有属性
  • in 操作符 同时可以判断 原型和实例中有没有属性 e.g console.log('name' in box)
  • 5.原型的 字面量
  • e.g
    function Box(){}
    Box.prototype={
    name:'yuan',
    age:12,
    run:function (){
    return this.name+this.age;
    }
    };
    var box1=new Box();
    shu(box1.run());


  • 6.内置引用类型的功能扩展:
  • e.g:
    String.prototype.addstring=function(){
    return this+'添加的字符串';
    }
    console.log('yuan'.addstring());
    String.prototype.addstring=function(data){
    return this+data;
    }
    console.log('yuan'.addstring(' ming'));


  • 7.使用原型的缺点:
    省掉了传参数;
    引用类型第一次修改后,保持了共享。
    原型里的已有的数据,不能改变。


    解决方式:
    1,使用组合模式:构造函数+原型模式;即保持独立的构造函数,保持共享的用原型;
    2,上面的方式是分开的,而最好的方式动态的原型模式;也就是封装。
    3,可以将原型封装到构造函数里。
    4,寄生构造函数:工厂模式+构造函数
    5,稳妥构造函数
  • e.g :
    function Box(name,age){
    this.name=name;
    this.age=age;
    
    if(typeof this.run !='function'){ //判断this.run 是否出现
    Box.prototype.run=function(){
    retrun this.name+this.age;
    }
    }
    }


  • 7.继承:原型链来实现 & 使用对象冒充继承
  • 被继承的函数叫做超类型(父类型,基类)
    继承的函数叫做子类型(子类型,派生类)
  • 使用:父类实例化对象后,赋值给子类型的原型属性;
    通过原型链继承 ,在继承的时候,如果属性一样的话,就近原则
  • e.g
    function Box(){
    return this.name='yuna';
    }
    
    function Table(){
    return this.age='tbable';
    }
    
    function Desk(){
    this.name='desk name';
    return this.height='zhuo';
    }
    
    Table.prototype=new Box(); //Table继承Box,是Box的子类
    
    Desk.prototype=new Table(); //通过原型链继承Table ,在继承的时候,如果属性一样的话,就近原则
    
    var box1=new Desk();
    
    shu(box1.name+box1.age)


  • 使用对象冒充继承:call()来对象冒充;可以解决传参问题!
    对象冒充,只能继承构造里的信息;
    构造函数里的方法,放在构造里,每次都实例化,造成浪费。
  • 组合继承(原型链继承+对象冒充继承)
  • 原型式继承:
  • e.g :
    //临时中转函数 
    function obj(o){ //o是传递的对象
    function F(){} //F 构造是临时新建的对象,用来存储传递过来的对象
    F.prototype=o; //将o 对象实例赋值给F构造的原型对象
    return new F(); //返回这个得到传递过来的对象的对象实例
    }
    
    var box={
    name:'yuan',
    age:20,
    arr:['ming','zhuo']
    };
    
    var box1=obj(box);
    shu(box1.arr);
    box1.arr.push('hpu');
    shu(box1.arr);
    
    var box2=obj(box);
    shu(box2.arr); //box 引用类型的数据共享了


  • 寄生继承:添加一个继承函数,这个寄生函数可以扩展;

    

e.g :在上面的基础上
function create(){
var f=obj(box);
f.run=function(){
return this.name;
};
return f;
}

4.匿名函数和闭包

  • 匿名函数:没有名字的函数。
    闭包是可访问一个函数作业域里变量的函数。即内部函数
    闭包可以把局部变量驻留在内存中,可以避免是用全局变量。
  • 实现:e.g :
    //通过赋值执行
    var box=function(){
    return 'ming';
    };
    shu(box());
    
    //通过自我执行
    (function (){
    shu('zhuo');
    })();
    
    //自我执行的传参
    (function (age){
    shu(age);
    })(100);
    
    //函数里放一个匿名函数
    function bo(){
    return function (){ //闭包
    return 'yuan';
    }
    }
    shu(bo()());
    var bo1=new bo();
    shu(bo1());
    
    //通过闭包返回局部变量
    function box2(){
    var age=1000;
    return function(){
    return age;
    }
    }
    shu(box2()());


  • e.g :
    //循环里的匿名函数取值问题:使其自我执行
    function box(){
    var arr=[];
    for(var i=0;i<10;i++){
    arr[i]=(function(num){ //自我执行!!!!!
    return num;
    })(i);
    }
    return arr;
    }
    shu(box()[0]);


  • 闭包中关于this对象 :闭包在运行时时指向window的,故闭包中的this是指向window的!
  • 内存泄漏问题:无法注销内存中的对象!
  • 私有化问题:
  • 模仿块级作用域:javascript没有块级作用域的概念!
  • 实现:()(); 包含自我执行的匿名函数,就可以实现私有作用域!当自我执行的私有作用域完毕后,就立即被销毁了!
  • e.g :
    function box(){
    //使用自我执行的匿名函数
    (function(){ 
    for(var i=0;i<10;i++){
    
    }
    })();
    shu(i); //i 没有值
    }


  • javascript没有私有属性的概念
  • 可以通过get & set 来实现
  • e.g :
    function box(){
    var name;
    this.setName=function (value){
    this.name=value;
    }
    this.getName=function(){
    return this.name;
    }
    }
    var box1=new box();
    box1.setName('yuanming');
    shu(box1.getName());


  • 私有变量和方法:也可以采用字面量的方式创建!
  • 单例:永远只实例化一次,其实就是字面量对象声明方式!

5.BOM

  • BOM:浏览器模式,提供了很多对象,用于访问浏览器功能!
  • window对象,location对象,history对象等
  • 1)window对象是最顶层的对象,有六大属性,这六大属性本身也是对象
  • 2)window对象旗下的 document属性也是对象,并且document对象旗下有五大对象,也是对象。
  • 3)window的属性和方法懂得调用:window.属性 ,window.方法()
  • 4)如果某个浏览器独有的属性和方法,那么在其他就懒起可能不识别,就当作普通的使用
  • 5)系统对话框:alert(); confirm();返回boolean值 prompt('内容','默认值');返回输入的内容
  • 6)打印:print(); 搜索:find(); 状态栏:defaultStatus=''; 和 Status=''
  • 7)新建窗口:open(); window.open() 参数:URL , 窗口的名称或者窗口的目标('_blank','_parent'),特定字符串 ; opener:可以实现子窗口控制父窗口!!!
  • 8)窗口的大小和位置:screenLeft和screenTop 火狐不支持;window.screenX和window.screenY IE不支持;
    跨浏览器支持:
    var left=typeof screenLeft=='number'?window.screenLeft:window.screenX;
    var top=typeof screenTop=='number'?window.screenTop:window.screenY;
  • 9)定时器:间歇调用和超时调用
  • 超时调用:实现:setTimeout(方法函数,毫秒数); e.g :setTimeout('shu(1)',2000);
    推荐这样写:扩展性好:
    setTimeout(function(){
    console.log('yuan');
    },1000);


  • clearTimeout() 取消当前的调用计划!
  • 间歇调用:可以重复不断的去执行:实现:
    setInterval(方法函数,毫秒数); e.g:
    var num=1;
    setInterval(function(){
    num++;
    console.log('yuan'+num);
    },1000);


  • clearInterval()
  • 使用超时调用来模拟间歇调用,使用递归调用!!!!
  • 10)window.location 和 window.document.location当前地址
  • 11)location.href()指向你想要去的地址 ;
    location.search() 获取url 问号后面的 ; 
    location.assign() 实现跳转 ;
    localtion.reload(true) 重新加载/参数为ture时,强制加载 ; 
    location.repalce('url') 不产生任何记录的调转!


  • 12)history:历史记录
    history.length 历史记录的数量;
    history.back(); 前面的记录
    history.forward(); 后面的记录
    history.go(num); 跳到记录

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值