JavaScript进阶学习

Javascript

1. 定义
基于事件和对象驱动,并具有安全性能的脚本语言。
2. 出现背景
上世纪90年代,在美国有出现,当时有上网的环境,并且有网站服务在运行。

网景公司发明了javascript语言,最初用于在客户端对表单域项目进行验证。
网景公司在1995年发布了javascript语言,起初名字为livescript,在发布的前夕该名字为javascript,与sun公司的java语言打一个擦边球,这个决定也使得网景后期得到许多商业回报。
微软公司也有自己的脚本语言,名字为Jscript(是javascript的拷贝版本)

  • 使用语法规范
① 在html代码里边引入js语言
    <script  type=”text/javascript”>具体js代码</script>
    <script  type=”text/javascript” src=”js文件”></script>
② 代码大小敏感
    true/false
    TRUE/FALSE
③ 结束符号
   每个简单语句使用”;”结束,与php类似
   在javascript里边,该分号不是必须,但是推荐使用
④ 注释
    //  单行注释
/*多行注释*/
⑤ 变量
    其值可以发生改变的量就是变量。
变量名字命名规则:
    php里边:字母、数字、下划线组成,开始有$符号标志,数字不能作为开始内容
    js里边:字母、数字、下划线、$符号、汉字 等5个组成部分,数字不能作为名字的开始内容。

⑥ 数据类型
php:int  float  string  boolean  array  object  null   resource
javascript(6种):  number(int/float)  string   boolean   null   undefined   object
          (数组是对象的一部分)

    null类型:空对象类型。

    
    var name = “”;      //声明一个变量,后期要使用一个“字符串”进行赋值
    var age = 0;        //声明一个变量,后期要使用一个“数字”进行赋值
    var obj = null;     //声明一个变量,后期要使用一个“对象”进行赋值
    
    undefined未定义类型
    使用一个没有声明的变量

    object对象类型:window  document

  • 数值类型
各种进制数表示
      十进制:  var  age = 23;
      八进制:  var  score = 023;  2*8+3=19的十进制数
      十六进制:  var  color = 0x25;  2*16+5=37的十进制数
        10:A   11:B   12:C  13:D  14:E   15:F

        
2. 浮点数 :5.32 , .98, 0.22

2. 最大数、最小数
最大:Number.MAX_VALUE;
最小:Number.MIN_VALUE;

4. 无穷大的数
5. Number.MAX_VALUE + NUMBER.MAX_VALUE;  //infinity


  • 运算符
算术运算符:+,-,*,/,++,--
比较运算符:>,>=,<,<=,!=,==,===(比较值的大小和类型),!==

逻辑运算符:&&,||,!

注意点:
1)逻辑运算符最终结果
在php里边,最终结果是“布尔”结果
在javascript里边,&&和||是其中一个操作数,!是布尔结果

2)短路运算
只给执行一个操作数,不执行另一个操作数,不被执行的操作数就被短路。


  • 流程控制
顺序结构
分支选择结构:if  elseif  switch
循环结构:while()   do{}while()   for()
1. 条件表达式switch用法
switch(){
case  表达式:
分支;
case  表达式:
分支;
}



2. 两个关键字break和continue
break:在循环、switch里边有使用
       跳出当前的本层循环
continue:在循环里边使用
   跳出本次循环,进入下次循环

多个循环嵌套使用:
标志flag:
for1
red:
for2
for3
break/continue;  //把for3给跳出 / 跳出本次的for3
//break  3;//php语法
break flag;   //continue flag;   把标志对应的for循环给做跳出操作
break red;    //continue red;

  • 函数
1. 什么是函数
有一定功能代码体的集合。
2. 函数的封装
2.1 传统方式
function  函数名(){}
该方式的函数有“预加载”过程,允许我们先调用函数、再声明函数
预加载:代码先把函数的声明放入内存。代码开起来是先调用、后声明,本质是先声明、后调用的。
函数名();
function  函数名(){}

函数先调用、后声明的条件是,全部代码在一个”<script>”标记里边。



变量赋值方式声明函数(匿名函数使用)
var  函数名 = function(){}
该方式没有“预加载”,必须先声明、后调用。



函数的参数
function  函数名(形参1,形参2,形参3=’abc’){}
函数名(‘tom’,23,’beijing’);//传递实参信息

实参和形参的对应关系:

没有默认值情况:
在php里边:实参的个数小于形参是不允许的
在javascript里边:实参与形参没有严格的对应关系

总结:
1. 数据类型:Number   String  Boolean   Null  Undefined   Object
console.log(typeof  信息);   判断信息的数据类型
2. 运算符
算术、比较、逻辑、连接
3. 流程控制
switch
break/continue
4. 函数
封装
参数


关键字arguments:
function  函数名(){}  //函数声明没有形参
函数名(实参,实参);  //调用的时候有传递实参
利用arguments可以在函数里边接收实参信息。

function func(){
    var len = arguments.length;
    
    if(0 == len){
        //do something
    }else if(1 == len){
        //do something
    
    }else if (2 == len){
        //do something
    }
}


callee关键字:
意思:在函数内部使用,代表当前函数的引用。
function f1(){
xxxx具体执行代码
arguments.callee();   //调用本函数(或者f1())
//都可以使得本函数执行,我们选择callee,其可以降低代码的耦合度。
xxxx执行代码
}
f1();
耦合:一处代码的修改会导致其他代码也要发生改变。
  在程序项目里边要开发低耦合度的代码。

函数返回值:
一个函数执行完毕需要返回具体的信息,使用return关键字返回信息。
在一定层度上看,全部的数据类型(数值、字符串、布尔、对象、null)信息都可以返回
return本身还可以结束函数的执行。

在函数内部返回一个函数出来。
在javascript里边,一切都是对象
在一个函数内部,可以声明数值、字符串、布尔、对象等局部变量信息,言外之意就还可以声明函数(函数内部还要嵌套函数),因为函数是对象,并且函数可以被return给返回出来。


函数调用:
 传统方式函数调用
    函数名();
 匿名函数自调用
(function(){})();


全局变量
php里边:1.函数外部声明的变量。
  2.在函数内部也可以声明全局变量(函数调用之后起作用)
  funciton f1(){
        global  $title;
        $title = “javascript”;
  }
    f1();
   echo  $title;
   
   
   
   javascript里边:1. 在函数外部声明的变量
              2. 函数内部不使用“var”声明的变量(函数调用之后起作用)


局部变量
    php里边:在函数内部声明的变量
    javascript里边:在函数内部声明的变量,变量前边有”var“关键字。


  • 数组
2. 数组声明
var arr = [元素,元素,元素。。。];
var arr = new Array(元素,元素,元素。。。);
var arr = new Array(3);
arr[0] = 元素;
arr[1] = 元素;

3. 获取数组长度
数组.length;
4. 数组遍历
沿着一定的顺序对数组内部的元素做一次切仅做一次访问,就是遍历。
for循环 遍历
for-in遍历

数组常用方法:
instanceof
push/unshift
pop/shift
indexOf/lastIndexOf

  • 字符串
    在javascript里边,字符串可以调用一些成员。
toUpperCase();
var content = new String("aaaa");
var content = new Array("aaddss");
  • eval的用法
接收一个字符串参数,把这个字符串作为代码,在上下文环境执行,并返回执行的结果.

eval("alert(232)");
var a = 12;
var b = 22;

console.log(eval("a+b"));  //34

总结:
1. 函数
    关键字:arguments/callee
    返回值:return关键字
               全部类型信息都可以返回
               内部嵌套的函数也可以返回(对象赋值有体现)
    函数调用:
            传统方式
            匿名函数自调用
                (function(){})();
    全局变量、局部变量
2. 数组使用
    声明:3种方式
    长度:length
    遍历:for   for-in
3. 字符串
    字符串可以调用成员
4. eval语句

  • DOM
介绍
dom: document  object  model  文档对象模型
DOM技术:
    php里边有:php语言 与 xml/html标签之间沟通的一个桥梁。
    javascript里边有:js语言 与 html/xml标签之间沟通的一个桥梁。

    
    为了方便javascript语言通过dom操作html比较方便,
把html标签的内容划分为各种节点:
文档节点(document)
元素节点
文本节点
属性节点
注释节点

dom就是学习利用javascript如何实现对html标签内容的增、删、改、查等操作


具体操作方法:
document.getElementById(id属性值);
document.getElementsByTagName(tag标签名称);
document.getElementsByName(name属性值);不推荐,有浏览器兼容问题,通常应用在form表单里边。



3. 文本节点获取
<div>hello</div>
需要借助div元素节点再获得其内部的文本节点.
var dvnode = document.getElementsByTagName(‘div’)[0];
dvnode.firstChild;  //(或调用lastChild)获得元素div内部的第一个子节点对象



兄弟节点
firstChild、lastChild:父节点获得第一个/最后一个子节点
nextSibling:获得下个兄弟节点
previousSibling:获得上个兄弟节点
childNodes:父节点获得内部全部的子节点信息
以上属性在主流浏览器(火狐firefox、chrome、safari、opera)中会给考虑空白节点。在IE浏览器中不考虑。



5. 父节点
节点.parentNode;



6.属性值操作

①   获取属性值
itnode.属性名称;   //只能操作w3c规定的属性
itnode.getAttribute(属性名称);  //规定的 和 自定义的都可以获取
②   设置属性值
itnode.属性名称 = 值;  //只能操作w3c规定的属性
itnode.setAttribute(名称,值); //规定的 和 自定义的都可以设置



属性节点获取
var attrlist = itnode.attributes;  //返回对应节点内部的全部属性信息,数组列表形式返回
attrlist.属性名称;   //获得具体属性节点



获得节点类型nodeType:
1------> 元素节点
2------> 属性节点

3------> 文本节点
9------> 文档节点



节点创建和追加:
节点创建
元素节点:document.createElement(tag标签名称);
文本节点:document.createTextNode(文本内容);
属性设置:node.setAttribute(名称,值);
节点追加:
父节点.appendChild(子节点);
    父节点.insertBefore(newnode,oldnode); //newnode放到oldnode的前边
    父节点.replaceChild(newnode,oldnode); //newnode替换到oldnode节点

    
节点复制操作:
被复制节点.cloneNode(true/false);
true:深层复制(本身和内部子节点都复制)
false:浅层复制(本身(包括属性)节点复制)
<div id=”apple”>hello</div>

节点删除:
父节点.removeChild(子节点);


dom对css样式操作:

<div style=”width:300px; height:200px; background-color:pink;”></div>
①   获取css样式
元素节点.style.css样式名称;
divnode.style.width;  //获取宽度样式
②   设置css样式(有则修改、没有则添加)
    元素节点.style.css样式名称 = 值;
divnode.style.width =‘500px’;设置div宽度样式

注意:
①   dom操作css样式只能操作“行内样式”(css样式分为 行内、内部、外部)
②   操作属性样式例如background-color/border-left-color,
需要变为backgroundColor、borderLeftColor,中恒线去掉,后边首字母大写。

  • 事件操作
1.什么是事件
通过鼠标、键盘对页面所做的动作就是事件。
事件一旦发生需要有事件处理,该处理称为“事件驱动”,事件驱动通常由函数担任
onclick  onmouseover  onmouseout  onkeyup  onkeydown  onblur  onfocus  onsubmit

2. 设置事件
2.1 dom1级方式设置
①<input  type=”text”  name=”username” onclick=”函数名称()” />
    function 函数名称(){this[window]}
②<input  type=”text”  name=”username” onclick=”过程代码var a=10;var b=20;alert(123);this[itnode]” />
③itnode.onclick = function(){this[itnode]}
④itnode.onclick = 有名函数名称;
    function 函数名称(){this[itnode]}
取消dom1级事件:
itnode.onclick = null;

以上是dom1级事件设置的4种具体表现形式,除了第①种(其代表window),其他三种方式的函数内部this都代表当前节点本身。
2.2 dom2级方式设置
主流浏览器方式(包括IE9以上 版本浏览器):
itnode.addEventListener(事件类型,事件处理[,事件流]);       //设置
itnode.removeEventListener(事件类型,事件处理[,事件流]);    //取消
IE浏览器方式(IE6/7/8):
itnode.attachEvent(事件类型,事件处理);      //设置
itnode.detachEvent(事件类型,事件处理);  //取消
    事件类型:就是我们可以设置的具体事件,例如onclick/onmouseover等
              主流浏览器方式没有”on标志”,例如addEventListener(‘click’,...);
              IE浏览器方式有”on”标志
    事件处理:事件驱动,可以是一个有名/匿名函数
              例如addEventListener(‘click’,function(){}/有名函数);
    事件流:true捕捉型、[false冒泡型]

    事件取消(removeEventListener/detachEvent)操作具体要求:
①   事件处理必须是有名函数,不可以是匿名函数。
②   事件取消的参数与绑定的参数完全一致(数量/内容)

dom2级事件设置的特点:
①   可以为同一个对象设置多个同类型事件。
②   事件取消也非常灵活。
③   对事件流也有很好的处理。



事件流:
多个彼此嵌套元素,他们拥有相同的事件,最内部元素事件被触发后,外边多个元素的同类型事件也会被触发,多个元素他们同类型事件同时执行的效果称为“事件流”

IE浏览器从开始到现在事件流始终是“冒泡型”,在IE9以后的版本支持捕捉、冒泡型。
网景的Navigator浏览器(现在火狐浏览器的许多血统来源于navigator浏览器)一开始的事件流是”捕捉型”。后期事件流有改进,针对捕捉型、冒泡型都可以支持。


事件对象
事件对象,每个事件(包括鼠标、键盘事件)触发执行的过程中,都有对应的事件对象,通过事件对象可以获得鼠标相对页面的坐标信息、通过事件对象也可以感知什么键子被 触发执行、通过事件对象还可以阻止事件流产生、阻止浏览器默认动作。

获得事件对象:
获得:
①主流浏览器(IE9以上版本浏览器):
    node.onclick = function(evt){evt就是事件对象}
    addEventListener(类型,function(evt){}/函数名字);
        function 函数名称(evt){}
    事件处理函数的第一个形参就是事件对象
② IE(6/7/8)浏览器
    node.onclick = function(){window.event事件对象}
    全局变量event就是事件对象


事件对象作用:
1) 获得鼠标的坐标信息
    event.clientX/clientY;    //相对dom区域坐标
    event.pageX/pageY;        //相对dom区域坐标,给考虑滚动条位置
    event.screenX/screenY;    //相对屏幕坐标

阻止事件流:
    event.stopPropagation();  //主流浏览器
    event.cancelBubble = true; // IE浏览器
    冒泡型、捕捉型都可以进行阻止,为了浏览器兼容处理,只考虑冒泡型。

阻止浏览器默认动作
    浏览器默认动作,注册form表单页面,提交表单的时候,浏览器的页面会根据action属性值进行跳转,这个动作称为“浏览器默认动作”。
    event.preventDefault();     //主流浏览器 
    event.returnValue = false;  //IE浏览器
    return  false;              //dom1级事件设置起作用


4) 感知被触发键盘键子信息
event.keyCode  获得键盘对应的键值码信息
通过事件触发时候获得的keyCode数值码信息可以对应键盘的键子信息。

5. 什么是加载事件onload
js代码执行时候,需要html&css的支持,就让html先执行(先进入内存),js代码后执行
js代码在最后执行的过程就是“加载过程”,通常通过“加载事件”实现加载过程
具体设置:
    <body onload=”加载函数()”>
    window.onload = 匿名/有名函数;  //推荐  

  • BOM
browser  object  model(浏览器对象模型)
通过BOM技术可以模拟浏览器对页面进行各种操作:创建子级页面、操作历史记录页面、操作地址栏等等



4. BOM浏览器对象模型
location.href;     
location.href=xxx;

(opener:调用父级页面)

  • 作用域链
变量在当前环境now、内部环境f1、内部深层环境f2/f3....都起作用的现象形成了一个链条,这个链条就称为变量的"作用域链"

外部环境变量可以给内部环境使用

作用域链的作用:
1 变量必须“先声明、后使用”
函数可以“先使用、后声明”,原因是函数有“预加载”过程(函数声明先于其他执行代码进入内存)。本质还是函数的声明在前,使用在后。

2.内部环境可以访问外部环境的变量,反之不然
3 变量的作用域是声明时决定的,而不是运行时

AO活动对象
AO: Active Object 活动对象
执行环境:
    js代码执行是有环境的
    该环境定义了其有权访问的其他数据
    环境有一个与之关联的“活动对象AO”
    环境中所有的变量和函数都是活动对象AO的属性
    全局环境是最外围的执行环境,活动对象是window对象
    执行环境中的代码执行完毕后就被销毁

4. 执行环境可以访问变量的类型及优先顺序


5. 重新认识全局变量和局部变量
全局变量:
声明:
① 在函数外部声明的变量
② 在函数内部不使用var声明的变量(前提是函数执行之后才起作用)

其是活动对象window的成员信息
在访问的时候,window是否设置都可以
局部变量:
声明:
在函数内部通过var声明的变量

其在一定范围内可以看做是“全局变量”。
其在本环境、内部环境、内部深层环境都可以被访问。

闭包
1. 什么是闭包
    闭包就是一个函数,两个函数彼此嵌套,内部函数就是闭包
形成闭包条件是内部函数需要通过return给返回出来.



function f1(){
    var age = 20;
    vae height = 180;
    function f2(){
        console.log("age: " + age + "height: "+ height);
    }
}

2. 闭包特点
    闭包有权利调用其上级环境的变量信息。
3. 闭包使用规则
同一个闭包机制可以创建多个闭包函数出来,它们彼此没有联系,都是独立的。
并且每个闭包可以保存自己个性化的信息。

  • 面向对象
PHP里边,是从一个类里边获得一个具体对象。
Javascript里边,没有类的概念,可以直接创建一个对象出来,对象可以有默认成员,后期也可以给对象丰富成员出来。

①   字面量方式创建
②   构造函数创建对象
③   Object方式创建对象

//1.字面量方式创建对象

var obj1 = {};
obj1.color = "red";
obj1["height"] = 90;
obj1.run = function (){

    console.log("I can running!");
}

var obj2 = {

    name:"ted",
    swim:function (){
        console.log("I am swiming!");
    }
};


//访问成员变量
console.log(obj2.name);
obj2.swim();


obj1['run']();


//2.构造函数方式创建对象
function Animal(){
    this.name = "dog";
    this.age = 88;
    this.run = function (){
        console.log("running...!");
    }
}

var dog = new Animal();
console.log(dog.name);
dog.run();


//3.Object方式创建
var cat = {color:'red'};

var rabbit = new Object();
rabbit.eat = 'robbot';
console.log(rabbit);  //Object{eat="robbot"}

2. 对象在内存分配
与对象有关系的内存区域:
①. 栈空间
存放的数据大小比较小,一般固定大小的信息适合存放在该空间,例如 整型、boolean、对象的引用(名称)。
②. 堆空间
该空间存储的数据比较多,空间较大,一般数据长度不固定的信息在该空间存放,例如: string、Array、对象实体
③. 数据空间
该空间存放常量、类的静态属性
④. 代码空间
存放函数体、方法体代码


3. 对象调用其他函数/对象成员
var name = "Joe";

function say(){
    console.log("name: " + this.name + "speaking");
}

//window.say();
var cat = {name:"kitty",eat:'fish'};
cat.express = say;

cat.express(); //name:kitty speaking!


/*
对象调用其它函数或者方法:
解决:把其它函数增加一个别名赋予给调用对象即可
*/

var cat = {name:"tom", eat:function(){console.log(this.name+'is eating')}};
cat.eat();//cat is eating

var dog = {name:'wangwang'};
//使得dog对象调用cat的eat方法

dog.eatdd = cat.eat;

dog.eatdd();//wangwang is eating.



4. 构造函数 与 普通函数
构造函数和普通函数的区别:
没有区别,就看使用,new就是构造函数,函数()就是普通函数调用。

5. 函数的各种执行方式
① 普通函数调用
② 构造函数执行new
③ 作为对象的成员方法执行
④ 通过call和apply执行
    call和apply可以明显控制变量污染的风险。

    
    
    /*
    call方式调用函数
    好处: 无需声明新的成员出来,就可以使得对象调用其它函数或者方法.
    对变量污染的风险进行了控制
*/

var cat = {name:"tom",eat:function(){console.log(this.name+" is eating!");}};
var dog = {name:"jet"};
var wolf = {name:"seven"};
//dog对象需要调用eat方法,通过call方式执行
//方法名称call(方法内部this的指针)
cat.eat.call(dog);  //this 指向jet
cat.eat.call(wolf);  //this指向seven

//2带参数调用

var cat = {name:"tom",eat:function(time){console.log(this.name+ time + " is eating!");}};
var dog = {name:"jet"};
var wolf = {name:"seven"};
//dog对象需要调用eat方法,通过call方式执行
//方法名称call(方法内部this的指针)
cat.eat.call(dog,"2018-09-09 20:00:00");  //this 指向jet
cat.eat.call(wolf,"2018-09-09 20:00:00");  //this指向seven


//3.

var name = "Ted";
function say(){

    console.log("name: " + this.name + "speaking!");
}

//call 使得函数执行,并任意设置函数内部指针的指向
//函数.call(this指针,参数...)
say.call(cat);


6. this都是谁
① 在函数/方法里边 代表调用该函数/方法的当前对象
② 在事件中,代表元素节点对象
divnode.onclick = function(){
alert(this.value);
}
③ 代表window
④ 可以任意代表其他对象
在call和apply使用的时候,可以任意设置被执行函数内部this的代表
7. 获取构造器
构造器:使用什么元素实例化的对象,元素就称为该对象的构造器

对象.constructor;  //获得构造器

//函数是一个对象,函数的构造器是"Function"

function getInfo(){
    alert(123);
}
//console.log(getInfo.constructor);//Function()
//通过实例化对象的方式,创建一个对象

//function func(name,age){console.log(name+"-->"+age);}
//var funcname = new Function('name','age',"console.log(name+"-->"+age);");

var func1 = new Function('name','age',"console.log(name+"-->"+age);");

func1('Ted',33);//Ted-->33


8. return对实例化对象的影响

/*
    return 的影响
    仍然实例化一个对象,return后边的代码不执行

*/

function Animal(){
    this.name = "hahaha";
    this.age = 22;
    return;

    this.run = function(){
        console.log("running!");
    }

}

var cat = new Animal();
console.log(cat);   //Animal{name="hahaha",age=22}

  • JS面向对象
三大特性:封装、继承、多态

在php里边,通过给成员声明关键字体现封装。public   protected   private

在javascript里边,封装只体现public、private
①   public公开的,在构造函数里边通过this关键字声明的成员都是公开的,函数内部、外部都可以调用
②   private私有的,在构造函数里边声明局部变量,就是私有成员



//封装的特性 public(this关键字声明的成员)/private(构造函数的局部变量)

function Animal(){

    //声明私有成员
    var secret = "run everyday!";
    var func = function(){};

    //公开成员
    this.leg = 4;
    this.run = function(){
        console.log('running!!!');
    }

    //对外公开的接口访问,内部可以访问私有成员
    this.fight = function(){
        //内部环境,可以访问外部环境的变量secret
        console.log('hahha ' + secret);
    }
}

var cat = new Animal();
console.log(cat.leg);
cat.run();
cat.fight();

//console.log(secret);  //secret is not defined



继承特性
2.1 原型继承介绍
php里边:一个类去继承另一个类,继承类实例化对象也会拥有被继承类的成员
javascript里边:(构造)函数可以继承另外一个对象,构造函数实例化出来的对象除了本身成员外还有拥有被继承对象的成员。
原型继承关键字:prototype。



2.2 实现原型继承
函数.prototype.成员名称 =  值;   //继承单一成员
函数.prototype = 对象;           //继承一个对象


var cat = {color:"red",run:function(){console.log("Running!");}};

function Animal(){
    this.leg = 5;
}

/*
    Animal构造函数去继承cat对象
    这样通过Animal实例化的对象会拥有本身的成员,也会拥有cat对象的成员
*/

Animal.prototype = cat;

var tigger = new Animal();
console.log();//{color,leg,run}



function Wolf(){
    this.eye = 'slight';
}

var seven = new Wolf();

function Dog(){
    this.tail = "wave";
}

Dog.prototype = seven;

var dog = new Dog();

console.log(dog);

//继承成员可以直接访问
console.log(dog.eye);  //slight



//构造函数 继承单一成员

function Dog(){
    this.tail = "wave";

}

Dog.prototype.color = "yellow";
Dog.prototype.hobby = function (){
    console.log("Guard home!");
}

var dog = new Dog();
console.log(dog);


原型继承注意
① 对象 和 单一成员同时继承,需要先继承对象、再继承成员
② 多个对象 同时继承,最后对象起作用
③ 继承对象的成员 与 本身成员名称一致,体现本身成员结果


/*
    继承prototype

    1.本身和父对象拥有同名的成员变量,调用的是自身的成员
*/

var seven = {tail:"笔直的尾巴",color:"gray",act:"夜间活动"};

function Dog(){
    this.tail = "摇动的尾巴";
}

Dog.prototype = seven;

var dog = new Dog();

console.log(dog);//Object {tail:"摇动的尾巴",color:"gray",act:"夜间活动"}

console.log(dog.tail); //摇动的尾巴



/*
通一个构造函数继承多个对象,后者覆盖前者
*/

var tigger = {weapon:"爪子"};
var seven = {tail:"笔直的尾巴",color:"gray",act:"夜间活动"};

function Dog(){
    this.tail = "摇动的尾巴";
}

Dog.prototype = seven;
Dog.prototype = tigger;

var dog = new Dog();
console.log(dog);//Object{tail:"摇动的尾巴",weapon:"爪子"}


/*
    对象和单一成员 同时继承,先对象.后单一成员
*/

var seven = {tail:"笔直的尾巴",color:"gray",act:"夜间活动"};

function Dog(){
    this.tail = "摇动的尾巴";
}

Dog.prototype = seven;

Dog.prototype.run = function(){console.log("running!")}

var dog = new Dog();
console.log(dog);//Object{tail:"摇动的尾巴",color:"gray",act:"夜间活动",run...}


3. 对象访问成员的类型及顺序


//对象访问成员类型和顺序
/*
    有四种: 1,2,3,4>>优先级从低到高
*/

function Wolf(){
    this.eye = "闪闪发光";
    this.color = ""gray;  //1.对象 构造函数 继承对象 构造函数的成员
}

var seven = new Wolf();
seven.color = "red";    //2对象 构造函数 继承对象本身 成员

function Dog(){
    this.tail = "摇尾巴";
    this.color = "yellow"; //对象 构造函数 成员
}

Dog.prototype = seven;

var dog = new Dog();
dog.color = "white";  //对象本身成员


console.log(dog.color);  //white


4.原型链

什么是原型链:
构造函数 继承 一个对象
继承对象也有构造函数,其构造函数还去继承其他对象
其他对象也有构造函数,构造函数还去继承其他对象
其他对象也有构造函数,构造函数还去继承其他对象
。。。。。
以上继承形成了一个继承的链条,称为原型链,原型链的顶端是Object

对象访问一个成员顺序:
① 对象本身获取
② 对象构造函数里边获取
③ 构造函数继承对象本身获取
④ 构造函数继承对象的构造函数里边获取
。。。。。。
直到找到Object成员为止。
例如constructor、hasOwnPrototype、isPrototypeOf等等都是原型链顶端Object的成员。



5. 对象遍历及成员属组判断
for-in
for  var  成员变量  in  对象
对象[成员变量]  //获得具体成员信息


/*
    对象遍历和成员属性判断
    for-in遍历对象
    obj.hasOwnProperty(成员名称) //判断成员是否是对象成员
*/

var cat = {age:2,weapon:"牙齿"};

function Tigger(){
    this.color = "yellow";
    this.act = function(){
        console.log("老虎吃饭");
    }
}

Tigger.prototype = cat;

var tigger = new Tigger();

for(var k in north){
    if (north.hasOwnProperty(k)) {
        console.log("本身成员: ") +k;
    }else {
        console.log("非本身成员: " + k);
    }
}

//结果
/*
本身成员: color,
本身成员: act,
非本身成员: age,
非本身成员: weapon,
*/



6. 原型衍生继承-复制继承

/*
    继承复制使用:本质就是给对象丰富成员出来,导致问题是:如果复制对象身上
    有同名的成员就会覆盖本身成员(类型编译语言的类别拓展)

复制继承的特点:
1.普通原型继承不能替代
2.可以根据需求灵活的给对象丰富成员出来
*/

var dog = {hobby:"Guard home!",eat:"boone",color:"white"};

var wolf = {tail:"笔直的尾巴",eye:"闪闪发光"};

function Animal(){
    this.color = "yellow";
    this.leg = 4;
}

Animal.prototype.extend = function(obj){
    //遍历obj对象,把其中的成员复制出来赋予给当前对象(this);
    for(var k in obj){
        //被复制的成员不在当前对象this里边才复制
        if (!this.hasOwnPropertyk) {
            this[k] = obj[k];
        }
    }
}


var kitty = new Animal();
//把dog对象的成员复制一份到kitty
kitty.extend(dog);
kitty.extend(wolf);

var obj = new (Animal);

console.log(kitty);


 静态成员
    如果一个类里边,有这样的属性,其值不随便发生变化,全部对象都共用一个值,该属性就声明为static静态的,其在内存中无论创建多少个对象(或者其说其与具体对象无关)都只占据一份空间。

为什么使用静态成员
① 静态成员归属到类本身,可以明显的加快访问速度。
② 节省内存效果



一个类,每实例化一个对象,在堆空间都要给每个成员分配内存空间,如果有一个成员country无论创建多少个对象其的信息值也不发生变化,为了节省内存空间的使用,就把这样的成员设置为“静态成员”。其在内存中就只占据一份空间。

静态成员在php里边需要通过类名直接访问,
那么在javascript里边如果一个成员是通过函数直接调用的,就称其为“静态成员”。

//静态成员

function Cat(){
    this.color = "yellow";
    this.age = 5;
}

var kitty = new Cat();

/*
    以上代码有两个对象,kitty,和Cat函数对象
    kitty可以访问color和age成员
    Cat通过如下代码可以访问addr和run成员
    普通对象和函数对象 彼此不能交叉访问(联系编译型语言的类成员变量)
*/

Cat.addr = "road 1";  //静态成员
Cat.run = function (){
    console.log("running!");
}

console.log(Cat.addr);//"road 1"
Cat.run();


console.log(kitty.addr); //undifined
console.log(Cat.color); //undefined


  • 异常处理
 什么是异常
异常是程序运行时的一种错误。
在没有异常的时候,程序遇到“问题/错误”通常就停止运行,给用户了一种不好的体验
使用异常后,即使程序有运行错误,我们也要把这个程序完整运行完毕,以便给用户好的使用效果。
8.2具体使用异常
try{
    有可能产生异常(错误)的语句
    如果其中一个语句有错误,就直接跳到catch执行,后续代码就不给执行了
xxxx后续代码
}catch(Exception ex){
    捕捉错误语句,通过ex对象获得具体错误信息
}finally{
    在php里边没有finally
    javascript和java里边有此finally

    无论代码是否有错误,该处代码都给执行
}



//exception

var title = "weather";

var content = "together";

try{

    console.log(title);
    console.log(content);

    var obj = new eval();//TypeError:eval is not a constructor
    console.log(obj);
}catch(ex){
    console.log(ex.message);
}finally{
    console.log('hahah');

}


异常使用注意
① 并不是全部代码都放到try里边,而是有可能产生异常的代码放到try里边
② 有一定容忍度的错误可以设置异常,敏感错误不要设置
③ 最后的finally根据情况需要可以不设置




9.多态体现
多态就是多种状态。

java里边有多态,其中方法重载是多态效果之一(多个同名方法,他们的参数个数不一样)体现多态.同一个名字的方法被多次调用,由于传递的参数个数不一样,导致请求的结果也不同。

php里边
继承抽象类可以体现多态,许多类都要把继承的抽象类的方法给实现出来。不同的类实现相同的方法有自己独特的实现,他们被调用的时候呈现不同的结果
工厂设计模式可以体现多态,实例化对象调用同一个方法,由于传递的参数不同,实例化的对象也不同。

javascript体现多态
① 在函数内部可以通过arguments关键字进行多态处理,传递个数不相同的参数,通过arguments判断,进而有不同的处理。
② this关键字可以体现多态。其可以任意代表其他对象(call和apply使用)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock阅读 3,370评论 2 36
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 翻身,应该是宝宝成长中的第一个大运动,相比于吃手指,蹬蹬腿来说,这个需要全身的配合。 我家宝宝,分解了三个阶段动作...
    细雨带风风风阅读 396评论 2 4
  • 倚阁凭遥,千里浪、幽云绕壁崖。雾烟城郭,惊涛穿孔,乱石鸦啼。望摩厓刻字,劲道雄、万古防堤。浪淘尽,楚勇乡军也,三两...
    刘小地阅读 398评论 25 87
  • 1、 徐逸成提起栾平的时候,我正将一小块鲈鱼片放入口中。鱼片很薄,在酸菜和红椒的爆炒下,鲜辣非常。我倒吸了一口气,...
    姜三疯阅读 7,337评论 17 82