优雅的JavaScript-面向对象
来源:互联网 发布:mac cr2转jpg 编辑:程序博客网 时间:2024/06/05 20:02
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body></body></html><script type="text/javascript">//通过构造函数创建对象 注意:构造函数和普通函数一样,为了区分一般首字母大写 //声明“类”,用来创建对象 function Person(name,age) { //声明属性,this:代表当前对象实例 this.name="张三"; this.age=18; //声明一个私有属性,私有属性就是外部函数无法访问到的 设置方法(访问私有变量) this.setHeight=function (height) { _height=height; } //取值方法(访问私有变量) this.getHeight=function () { return _height; } 声明方法 this.sayHello=function () { alert("大家好,我是"+this.name+",我的年龄:"+this.age); } } //给Person添加一个静态方法(类方法),静态方法是直接通过构造函数的名称调用的,不用关心是否有对象实例的存在 如:Math.random(); Person.staticFu=function () { alert("z这是一个仅仅直接用构造函数名字调用的静态方法") } //一般我们可以用静态方法区创建对象,可以简化代码,实质上new+构造函数创建对象 Person.createPerson=function (name,age) { var tempPerson=new Person(name,age); return tempPerson; }//通过Person构造函数创建一个对象实例 注意:通过new和构造函数去创建问题: new Person 在内存中做了什么,,通过new 关键字创建的对象,都会存在堆内存中 只要看到new+构造函数,就代表在堆内存中开辟了一个空间(对象)。同时生产一个地址,如果需要访问这块空间 只能通过指针变量来访问 var person1=new Person("张三",9); //用对象调用方法 person1.sayHello();var person2=person1;这里没有生产新的对象,而是person2指针指向了和person1指针相同的内存地址 //修改person2的名字,年龄 person2.nam="李四";person2.sayHello();//结论: person1和person2指向的是一个对象 还可以直接判断两个指针是否指向同一块内存空间 alert(person1===person2);在创建一个新的对象 var person3=new person("sfs",19);instanceof运算符来判断一个变量是否是通过某个构造函数创建出来 typeof:判断类型 //使用静态 Person.staticFu();</script>
原型模式创建对象
概念: 每个构造函数都有一个原型属性(prototype) 这个原型属性指向一个原型对象,可以给原型对象声明属性和方法,这个属性和方法可以通过构造函数创建出来的对象实体使用。 或者理解为: 每个构造函数创建出来的对象实例,继承与这个原型对象的属性和方法 ,原型模式创建对象其核心还是通过构造函数创建对象,只不过方式是通过原型模式创建<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body></body></html><script type="text/javascript">//狗的构造函数 function Dog(name) { this.name=name; this.bark=function () { alert("小狗叫") }// 全局函数虽然可以解决函数共享问题,但一般不要使用《生命周期太长this.bark=globalFn; }//创建一个全局函数,这样可以解决每一次创建独享都要开辟一个内存空间去存储function function globalFn() { alert("dsfd"); } //通过Dog的原型对象声明bark方法,这样也可以达到函数共享 Dog.prototype.bark=function () { alert("原型,vdv"); }创建一个狗的对象 var dog1=new Dog("das"); var dog2=new Dog("asd");// 验证:// 两只狗的bark方法是否指向同一个对象 console.log(dog1.bark===dog2.bark);</script>
原型链
每个对象都要一个原型对象,而原型对象也是一个对象,也会有对应的原型对象,以此类推,直到Object.prototype(注意:Object.prototype吃的原型为null),例如: a对象是b对象的原型对象,b又是c的原型对象,这样就形成了原型链,c对象可以访问其原型脸上的任何对象里的属性和方法 <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body></body></html><script type="text/javascript">原型相关的属性和方法: constructor属性:每个原型对象都有一个constructor属性,这个属性默认是该原型对象所在的构造函数 obj.hasOwnProperty("属性")方法:用来判断某个对象里是否存在某个属性 Object.getPrototypeOf(obj)方法:返回一个对象的原型对象 Object.create(obj):根据接受参数对象,创建一个新的对象,前者是这个新对象的原型对象 obj.isPrototypeOf(obj2):判断一个对象是否是另外一个对象的原型对象 function Cat() { }//动物的构造函数 function Animal() { this.name="动物"; } //给Animal构造函数设置原型对象 //{}:表示字面量创建对象,其内部的语法复合JSON语法格式 Animal.prototype={ sex:"男", sayHello:function () { alert("大家好"); } } //给Cat构造函数设置原型对象 Cat.prototype=new Animal();//创建一个猫的对象 var cat1=new Cat(); //cat1对象先去找自身的构造函数是否有name.age.sex等属性和方法, 如果有:直接使用自己的 如果没有:就沿着原型链往上找,找到就使用,如果找不到,直到找到最根部Object.prototype为止</script>
属性访问器
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body></body></html><script type="text/javascript">//人的构造函数 function Person() { //私有属性 var name="123"; //给当前对象的name属性添加set和get访问器 Object.defineProperty(this,"name") set:function (newName) { if(newName="小明"){ name=newName; return; } };get : function(){ alert("name")} }</script>
This关键字
在js中所有的函数都运行在某个运行环境中,对于js而言,一切皆是对象,运行环境也是对象,函数中的this关键字的指向,也是根据当前对象(运行环境)而定在js中,因为js是动态脚本语言,运行环境也是动态切换,也就是说:this关键字的指向也是动态切换<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body><input type="button" value="这是第一个按钮" onclick="btnClick(this)"/><input type="button" value="这是第而个按钮" onclick="btnClick(this)"/></body></html><script type="text/javascript">//在构造函数在,this指向的就是该构造函数所创建的实例对象 function Person() { this.name="asc"; } var Person1=new Person(); Person1.name="ads"; //this在这种运行环境中,代表当前点击的按钮对象 function btnClick() { alert("vdsgfh"); }运行环境动态切换,this指向也跟着动态切换 function fn() { console.log(this.name) }创建一个字面量对象 var a={ name:"a", aFn:fn }a.aFn();</script>使用场景: <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body><input type="button" value="这是第一个按钮" onclick="btnClick(this)"/><input type="button" value="这是第而个按钮" onclick="btnClick(this)"/></body></html><script type="text/javascript">//使用场景 1.全局运行环境 console.log(this===window);//true 2.构造函数中 function Person() { this.name="张三"; } Person.prototype.say=function () { alert(this.name); }var person=new Person(); person.say(); 3.在对象方法中 var a={ name:"a",aFn:function () { console.log(this.name); } } var b={ name:"b",bFn:a.aFn }b.bFn(); 4.常见的问题: 如果某个对象的层次结构很深,我们想把某个方法提取出来,不能直接提取方法,而是提取方法所在的对象 var c={ d:{ aa:"liu", fn1:function () { console.log(this.aa); console.log(this===window); } } }//提取fn函数 var myFn=c.d.fn1;//这样提取的话,函数内部的this指向变成window对象 myFn();//undefinded如果想把fn函数提取出来,而且不改变this指针,那么就提取fn函数所在的对象 var maobj=c.d;maobj.fn1();//liu 总结: 1.全局环境中:this指向的是最顶端window对象 2.构造函数中:this指向的是该构造函数所创建的实例对象 3.对象方法中:如果某个对象的方法赋值给了另外一个对象的某个方法,那么方法内部的this指向也会发生变化</script>
作用域
定义:变量和函数访问的范围,作用域可以控制变量和函数的可见性和生命周期在js中作用域大概分两种: 1.全局作用域 2.局部作用域 <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body><input type="button" value="这是第一个按钮" onclick="btnClick(this)"/><input type="button" value="这是第而个按钮" onclick="btnClick(this)"/></body></html><script type="text/javascript">//全局作用域//这是一个全局变量,已经处于全局作用域中,也就是说在任何位置都可以访问到这个全局变量 var globalName="这是全局变量"; //在全局作用域中访问 console.log(globalName);//在普通的函数中访问 function fn() { console.log(globalName); }fn(); //在构造函数中访问 function Person() { this.name=globalName; }var person=new Person(); console.log(person.name); //在字面量对象中访问 var obj={ name:globalName }console.log(obj.name); /*局部作用域*/function fn2() { var partName="这是局部变量"; //局部变量在当前作用域一定可以被访问 alert(partName); function sunfn() { alert("某个函数的子函数(内部函数)也可以访问到当前函数的局部变量"+partName); } sunfn();}//会出现异常,try...catch语句:用来捕捉异常(影响成像运行的一些错误)如果用try...catch来捕捉异常,当异常出现,程序照样会执行 一般觉得有风险的地方就使用try...catch try{ //把觉得有风险的代码写在try代码块里面、 console.log(partName); }catch(exception){ //捕捉异常后打印异常信息 console.log(exception.toString()); } 注意事项: //1.在js中是没有块级的概念 function fn() { for(var i=0;i<5;i++){ } }//可以访问到i console.log(i); //2.不用var声明的变量是全局变量 function fn2() { name="asd"; }fn2(); //可以访问到不用var声明的变量 console.log(name); 练习: var a="a"; function fn3(d) { b="b"; var c="c"; function subFn() { var e=d; if(true){ var f="f"; console.log(e); } console.log(f); } sunfn(); } fn3("d"); console.log(b); 注意: 1.在js中,没有块级(大括号)的概念,在其他语言都有块级概念,在块级变量中的变量就是局部变量,但在js中的块级中的变量不是局部变量,在js中,只有在函数中的才是局部变量 2.在js中,如果没有用var声明变量的话,那么这个变量就是全局变量,在任何位置都可以被访问</script>
作用域链
定义:作用域可以理解和原型链意思差不多也就是访问某个变量,先去当前的作用域去查找这个变量,如果找不到,就沿着作用域链向上找,以此类推,直到最顶端的window对象,全局作用域<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body><input type="button" value="这是第一个按钮" onclick="btnClick(this)"/><input type="button" value="这是第而个按钮" onclick="btnClick(this)"/></body></html><script type="text/javascript">//作用域链 var name="aaa"; function fn() { var name="abc"; function sunfn1() { var name="bcd"; console.log(name); } function sunfn2() { console.log(name); } subfn1(); //其原理:当调用subfn1函数时候, 会把subfn1所在的执行环境放到作用域链的最底端, 然后将fn()函数执行环境放到他的上面,最后放到全局的执行环境//subfn1----->fn---->window //subfn2(); /subfn2----->fn---->window }</script>
固定This的方法
js中this关键字的指向是动态的,动态有好处也有坏处,有时候会出现意想不到的结果,此时需要通过一些方法来固定this,call()/apply()1.call方法:可以指定函数内部的this指向,并且运行该函数2.apply方法:和call方法功能一样,只不过参数为数组<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> </style></head><body><input type="button" value="这是第一个按钮" onclick="btnClick(this)"/><input type="button" value="这是第而个按钮" onclick="btnClick(this)"/></body></html><script type="text/javascript">1.call方法 var name="abc";var obj={ name:"bcd"} function fn() { console.log(this.name); } fn();//通过函数调用call方法,可以改变this 的指向,并且在参数所在的运行环境中运行 fn.call(obj); //带参数 function fn2(a,b) { console.log(a+b); }//在全局环境中运行 fn2.call(this,5,8); //apply方法 fn2.apply(this,[6,9]);</script>
阅读全文
0 0
- 优雅的JavaScript-面向对象
- JavaScript面向对象程序设计(8): 优雅的封装还是执行的效率?
- JavaScript面向对象程序设计(8): 优雅的封装还是执行的效率
- 面向对象的javascript
- javascript的面向对象
- JavaScript的面向对象
- 面向对象的JavaScript
- Javascript的面向对象
- 面向对象的JavaScript
- 面向对象的JavaScript
- 面向对象的JavaScript
- 面向对象的Javascript
- 面向对象的JavaScript
- javascript的面向对象
- 面向对象的JavaScript
- JavaScript的面向对象
- 面向对象的JavaScript
- 面向对象的JavaScript
- openCV canny边缘检测
- 写递归函数的正确思维方法
- AsyncTask框架
- 笔记,安卓上简单的surfaceview使用
- www.conf
- 优雅的JavaScript-面向对象
- Spring Boot 整合 Redis 实现缓存操作
- 数组的冒泡排序
- 详解EVENTLOGRECORD结构体遇到的问题
- TCP非堵塞IO的connect连接处理模型
- 13. Servlet 请求/响应过滤器
- DVWA下的SQL Injection(Blind)
- 云服务器不能启动数据库代理服务,启动后报错
- php-fpm调优以及开启nginx和php-fpm的status状态监控