首页 > 技术文章 > 关于js

javascript9527 2019-09-18 21:48 原文

什么是js?

    概念 : JavaScript 是一种运行在 客户端 的 脚本语言

 

语言 :

  • 编译语言:Java/C/C++/OC/Swift... 运行代码之前,把所有的代码先编译一遍,再运行每一行代码(先编译找语法错误,然后再一行一行执行里面的逻辑)
  • 脚本语言:JavaScript/PHP/Python... 运行一行解析一行,不需要提前编译 , 非编译语言

 

javascript的组成

  • ECMAScript  (标准) JavaScript的核心,描述了语言的基本语法和数据类型,ECMAScript是一套标准,定义了一种语言的标准,与具体实现无关
  • DOM:一套操作网页元素的API
  • BOM:一套操作浏览器功能的API

 

 输出语句 (5种)

alert : 警告框

//alert会弹出一个警告框
alert("hello world");

 

confirm : 确认框

//confirm弹出一个确定框
confirm("hello word");

 

prompt : 输入框

//prompt:弹出一个输入框,可以输入值
prompt("hellow");

 

document.write : 网页中写入内容

//可以识别标签
document.write("hello world");
document.write("<h1>hello world</h1>");

 

控制台输出

//F12打开控制台,在console中可以看到打印的信息
console.log("hello word");

 

变量的命名规则和规范

规则 : ( 必须遵守的,不遵守会报错 )

  • 字母数字下划线$符号组成 ;

  • 不能以数字开头

  • 区分大小写

  • 不能关键字保留字 (不用死记 , 慢慢就见多了)

  //关键字:对于js来说有特殊意义的一些单词
  //保留字:js保留了一些单词,这些单词现在不用,但是以后要用。

关键字:

 

 

保留字:

 

 交换两个变量的值

 var temp = a;
        a = b;
        b = temp;

 

不使用临时变量,交换两个数值变量的值

var a = a+b; 
    b = a-b; 
    a = a-b;

 

数据类型

javascript中数据类型分为简单数据类型复杂数据类型

简单数据类型(基本数据类型)

    number、string、boolean、undefined、null

    数值       字符串    布尔       声明未赋值  空类型

 

复杂数据类型:

    函数 function

    数组 Array

    对象 Object

 

关于进制

在javascript中表示一个数字,除了有我们常用的十进制11, 22,33等,还可以使用八进制、十六进制表示等。

  • 八进制
  •         // 八进制  0-7  逢八进一  0开头的
    
            var num = 010;  // 10 = 0 * 8 ^0 + 1 * 8^1 = 8
            var num1 = 0123; // 123 = 3 * 8^0 + 2 * 8^1 + 1*8^2 = 3+16+64 = 83
            console.log(num1);

 

  • 十六进制
  •         // 十六进制  0-15 (0-9 a b c d e f )  逢十六进一  0x开头
            var num1 = 0x10; // 10 = 0*16^0 + 1 * 16^1 = 16;
            var num2 = 0x131; // 131 = 1*16^0 + 3*16^1 + 1*16^2 = 1 + 48 + 256 = 305;
            console.log(num2);

    关于二进制,计算机在只认识二进制,所以所有的代码最终都会转换成二进制数据。

 

 浮点数

  浮点数就是小数,,比如0.1

  • 浮点数精度丢失问题
  •      var num1 = 0.1;  // 大部分出现在奇数 
         var num2 = 0.2;
         console.log(num1  + num2); //0.30000000000000004
    
          // 解决 : 后面学到的 往上取整,,往下取整  四舍五入
          // 转化为整数进行计算

 

  • 科学计数法
//当一次数字很大的时候,可以用科学计数法来表示
var num = 5e+5;  //5乘以10的5次方
var num = 3e-3;//3乘以10的-3次方



 数值范围

最小值:Number.MIN_VALUE,这个值为: 5e-324
最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
无穷大:Infinity    1/0
无穷小:-Infinity

 

关于 typeof 

      function fn () {

      }
      var ary = [1,2,3]
console.log( typeof 1)                    // number
console.log( typeof 'a')                  // string
console.log( typeof true)                 // boolean
console.log( typeof undefined);           // undefined
console.log( typeof null);                // object
console.log( typeof fn);                   //function
console.log( typeof Array);                //function
console.log( typeof Object);                //function
console.log( typeof ary);                  //object

 

字符串类型

  字符串类型,使用双引号 " 或者 ' 包裹起来的字符



转义字符

 

 

      总结 : 
      //1. 引号可以相互嵌套的,,但是不能嵌套自己类型
      // 单引号可以嵌套双引号,双引号可以嵌套单引号,单不能嵌套单,双不能嵌套双
      //2. 转义符 
      // \' =>'
      // \" =>"
      // \\ => \
 
 
 

运算符优先级

  • ()的优先级最高
  • 一元运算符(++, --, !)
  • 算术运算符(先*/%, 后+-
  • 比较运算符 (先> < >= <=, 后== === != !==)
  • 逻辑运算符(先&&||



// == (等于)   === (全等于  恒等于)
 // 内容         内容 + 类型
 console.log( 12 == '12' ); // true
 console.log( 12 === '12' ); // false

 
 // != (不等于)    !== (不全等于) 
 console.log( 12 != '12' ); // false
 console.log( 12 !== '12' ); // true



类型转换
转为数字
Number()   转换为数字
parseInt()   转化为整数,会把小数点后边的删掉
parseFloat() 转化浮点数的时候用
+  可以将字符在转为数字
var num = +'2'
console.log(typeof num) // number

var num = null
console.log( Number(null)) // 0

var num = undefined
console.log( Number(num))   //NaN
console.log( typeof NaN)    //number

总结
1 NaN  ====    not a  number
2 NaN 是 number类型(NaN是数字类型)
3 NaN 的比较,它不等于任何一个值,连自己都不等于
4 isNaN() 判断是不是数字, 如果返回 true表示 不是数字   如果返回false表示 是数字
 
 
 
 
转化为字符串
01 String()
02 toString()
03  + '' 
var age = 666;
var s = '';
console.log( age + s);
*/
 
 
转化为布尔类型
     // 转化为 布尔类型  true/false  

      //1. 构造函数 Boolean() 
      var age = 'abc';
      console.log( Boolean(age) ); // true

      //1. 记忆那些 转化为false 
      //   没有值的 => false 
      //   非正常值 => false
      //2. 五大数据类型 
      // 数字类型 0
      // 字符串 ''
      // undefined 
      // null 
      // NaN 

    
      console.log(Boolean(0));    //false
      console.log(Boolean(''));     //false
      console.log(Boolean(undefined)); //false
      console.log(Boolean(null));   //false
      console.log(Boolean(NaN));    //false

      // 注意点 :
      // console.log( Boolean('false') );
      

      //2. !! 取两次非  
      console.log(!!123);
      console.log( Boolean(123) );


      // 总结
      //1. 转化为数字
      //1.1 构造函数  Number();
      //1.2 方法 : parseInt(值)  parseFloat()
      //1.3 + -0 

      //2. 转化为字符串
      //2.1 构造函数 String()
      //2.2 值.toString()  
      //2.3 + '' 


      //3. 转化为布尔
      //3.1 Boolean() 
      // false
      // 0 '' undefined null NaN

      //3.2 !! 取两次非

 

 

switch语句

switch (变量) {
  case 值1:
    语句1;
    break;
  case 值2:
    语句2;
    break;
  case 值3:
    语句3;
    break;
  …
  default:
    默认语句;
    break;
}
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串'10' 不等于数值 10)
 
switch (num) {
      case 0:
        console.log('星期天');
        break;
      case 1:
        console.log('星期一');
        break;
      case 2:
        console.log('星期二');
        break;
      case 3:
        console.log('星期三');
        break;
      case 4:
        console.log('星期四');
        break;
      case 5:
        console.log('星期五');
        break;
      case 6:
        console.log('星期六');
        break;
      default:
        console.log('你输入的有误');
        break;
    }

 

 

 

while循环

//当循环条件为true时,执行循环体,
//当循环条件为false时,结束循环。
while(循环条件){
  //循环体:需要循环执行的语句
}

 

//1. 打印1-100之间所有的数
//2. 计算1-100之间所有数的和
// 初始化变量
var i = 1;
var sum = 0;
while(i <= 100){//判断条件
  sum += i;//循环体
  i++;//自增,修改循环条件(不能省略)
}
console.log(sum);

 

 

do..while循环

do..while循环和while循环非常像,二者经常可以相互替代,但是do..while的特点是不管条件成不成立,都会执行一次。

do {
    //循环体;
}while(条件)
//初始化变量
var i = 1;
var sum = 0;
do{
  sum += i;//循环体
  i++;//自增
}while(i <= 100);//循环条件

 

 

创建数组 方法

      // 创建数组
      //1.1 创建空数组  以后用构造函数创建的对象 ( new Array() )
       var arr1 =  new Array();
       console.log(arr1); // []
       
      //1.2 创建一个有内容的数组
      var arr2 = new Array(1,4,7);
      console.log(arr2); // [1,4,7]

      //1.3 Arrar() 里面放一个值,代表的是创建一个长度为4的空数组
      var arr3 = new Array(4);
      console.log(arr3); //  [empty × 4]
      
      



//2. 字面量 直接量: 一眼就能看出是什么类型 // 是我们最常用的方式 简单粗暴 //2.1 创建一个空数组 var arr1 = []; console.log(arr1); //2.2 创建一个有内容的数组 var arr2 = ['zs','ls']; console.log(arr2); //2.3 也来尝试一下一个值 var arr3 = [40]; console.log(arr3); // [40]

 

 

 如何存储?

    存储基本类型存储的是值,存储引用类型存储的是地址

 

数据类型

  数字:  整数  小数   

  字符串: " "   ' '

  布尔:true false

  null

  undefined

  对象  { }  数组   函数  伪数组   元素   

 

操作符

短路与&&

  console.log(  1&&2  )   //   2   第一个满足条件,第二个也满足条件,输出第二个

  console.log(  1&&0  )   //   0   第一个满足条件,输出第二个

  console.log(  0&&1  )   //   0    第一个0已经是false了,后边的就不会看了  所以直接输出 0

 

短路或 ||

  console.log(  1||2  )       // 第一个已经满足条件,就不看后边的了,直接输出 1

  console.log(  0||1  )       //  第一个不满足条件,输出第二个

  console.log(  0|| ' ' )     //  输出  ' '

 

console.log(  !1  )    //false

console.log(  !!1  )    //true

console.log( +true )  // 输出   1

console.log(  +false  )   //输出  0

console.log(  +' '  )        // 0 

 

 

 

什么时候是加的逻辑?什么时候是拼接字符串?

    如果 + 号只有一个操作数,那么 就是把 操作数 转换为 数字类型   比如   console.log( +true )  // 输出   1             

    如果 + 号有两个操作数,并且其中有一个是字符串,那么一定是拼接字符串  如 console.log(  1+'false'  )     //输出 1false

            

 

console.log( Number('1.1111') )      // 1.1111

console.log( Number(false) )         //   0

console.log( Number(null) )            // 0 

console.log( Number(undefined) )   // NaN

 

 

 4.数据类型的转换
   其他类型转字符串:
     String(其他类型);
     其他类型.toString();
     + 拼接字符串
   其他类型转数字:
       Number()
           1. 可以转除字符串外的其他数据类型
           2. 如果字符串中有非数字类型,那么转的是NaN
       parseInt()

       parseFloat()

         parse系列的相同点:
          1. 只能把字符串类型转换成数字类型
          2. 如果字符串中有非数字字符,根据非数字字符的位置去转换
             '123a456'  -- > 123
             'a123'  -- > NaN
           parse系列的不同点:
             parseInt() 转换成整数
             parseFloat() 可以转换成浮点数
       +
        
       其他类型转布尔:
         Boolean(其他类型)
         !!
  
         字符换转布尔: 空字符串是false, 其他都是true
         数字转布尔: 0是false, NaN是false, 其他都是true
         null转布尔 : false
         undefined转布尔: false
         对象转布尔: true

 

 

js的内置对象

    js内置对象就是指JavaScript自带的一些对象,供开发者使用,这些对提供了一些常用的功能

    常见的内置对象有Math Sting Array Date() 等

 

Math对象

Math.PI     表示 π
Math.max();       最大值
Math.min();       最小值
Math.ceil();//天花板,向上取整
Math.floor();//地板,向下取整
Math.round();//四舍五入,如果是.5,则取更大的那个数
Math.random();//返回一个[0,1)之间的数,能取到0,取不到1
Math.abs();//求绝对值
Math.pow(num, power);//求num的power次方
Math.sqrt(num);//对num开平方

var max =  Math.max(1,4,7,2,5,8); 
console.log(max); // 8

console.log( Math.abs(-1));  // 1
console.log( Math.abs(1));   // 1

 // Math.pow(a,b)   a的b次方 
 console.log( Math.pow(5,2)); // 25 

// Math.sqrt 开方 
console.log( Math.sqrt(81) ); // 9

 

 

 

 

Date对象

当前时间
var date = new Date() //月  9                 格林时间,东八区
console.log(date);  // Mon Sep 30 2019 12:39:01 GMT+0800 (中国标准时间)s
                    // 9月30日 2019 年  12点30分   格林时间,东八区
格式化时间
console.log( date.toLocaleString() );       //2019/9/30 下午12:43:52
console.log( date.toLocaleDateString() );   //2019/9/30
console.log( date.toLocaleTimeString() );   //下午12:46:39


指定时间
var date = new Date("2019-06-22"); //创建一个指定时间的日期对象
console.log( date ) // Sat Jun 22 2019 08:00:00 GMT+0800 (中国标准时间)

var date = new Date("2019-06-22 08:08:08");//创建一个指定时间的日期对象
console.log( date ) //Sat Jun 22 2019 08:08:08 GMT+0800 (中国标准时间)

获取具体的日期时间
var date = new Date()
console.log( date.getFullYear() );  //  2019   获取年
console.log( date.getMonth() + 1 ); //  9      获取月
console.log( date.getDate() );      //  30     获取日
console.log( date.getDay() );       //  1      获取星期  ,输出1代表星期一
console.log( date.getHours() );     // 12      获取小时,  输出12代表12点
console.log( date.getMinutes() );   // 59      获取分钟,  输出59代表59分钟
console.log( date.getSeconds() );   // 10      获取秒,    输出10代表10秒

 
时间戳
什么是时间戳? 从1970年1月1日 到  现在的总共毫秒数
var date = +new Date()
console.log( date ); // 1569819727601

 

 

 

 

 

数组中常用的方法:

    数组.concat( 另一个数组 )  把两个数组合并成一个

    join( )  把数组转化成字符串

       split()  按照指定的字符将字符串分隔为数组  

 

      join('-')  将数组中的元素按照指定的字符分隔转换为字符串,默认是逗号。 (split()  按照指定的字符将字符串分隔为数组    字符的方法  )
      slice(开始下标,结束下标)  包含头,不包含尾   原来的数组没有发生变化,返回一个新的数组
      splice(开始下标,截取的长度,删除后补充的元素)  返回一个新的数组,原理的数组发生了变化
      push()  从后边加
      pop()   从后边删
      unshift() 从前边加
      shift()   从前边删
      var result = arr.forEach(function(elem,index,self){// elem 是数组中的每一项元素   index是数组的每一项下标  self 当前遍历的数组
            依次遍历数组中的元素,将数组中的元素执行相同的操作,不会改变原数组
      });

      var result = arr.filter(function(elem,index,self){ // filter 过滤
            return 判断条件 
      })
      var result = every(function(elem,index,self){
            return 如果数组中每一项都符合要求就返回true,否则返回false
      }) 
      var result = some(function(){
           return 只要有一些符合要求,就返回true
      }) 
       var result = arr.map(function(elem,index,self){
             return  遍历数组中的每一项元素,返回一个新的数组
     })

 

  

作用域

  代码一旦书写完毕,那么作用域就形成了,跟调用函数没有关系

  外部作用域不能访问函数作用域的变量,函数作用域内部可以访问外部

  访问变量的时候,先在自己的作用域中查找,如果找不到就沿着作用域链往上找,直到全局

  如果只是访问变量,如果找到全局都没有的话会报错, xx is not undefined

  如果要给变量赋值,找到全局都没有的话,浏览器会帮我们自动帮我们创建这个变量

  给变量赋值之前,或者访问变量之前,要先找到变量

  如果代码执行之前,要考虑预解析规则,函数的代码执行之前,也要执行预解析规则

  

 

<script>

// 知识点  xx in window   window中有没有xx,如果有返回true,如果没有false

var a;
if ( 'b' in window){   //console.log(  'b' in window ) //false  在window中找不到'b'所以 是false
      console.log(111)
      var a = 10
      console.log(a)
}
alert(a) // undefined
</script>

 

<script>

function fn1(){
     var a = b = c = 1;

//      var a = 1
//          b = 1
//          c = 1

   }
   fn1();
   console.log(c);  // 1
   console.log(b);  // 1
   console.log(a);  // a is not defined
</script>

 

<script>

var a = 1;
function fn () {
      var a = 2;
      function fnSon (a) {
            a = 3;
            console.log( a )  // 3
      }
      fnSon();
      console.log( a ) // 2
}
console.log( a )  // 1
fn()
console.log( a ) // 1

// 输出结果 :  1 3 2 1

</script>

 

<script>

var a = 1;
function fn () {
      var a = 2;
      function fnSon () {
            a = 3;
            console.log( a )  // 3
      }
      fnSon();
      console.log( a ) // 3
}
console.log( a )  // 1
fn()
console.log( a ) // 1

// 输出结果 :  1 3 3 1

</script>

 

 

<script>

var a = 1;
function a () {
      a++
}
console.log(a) // 1

</script>

 

 

<script>
// 解题知识点:在给变量赋值之前要先找到变量(记住了 a 和 a.x的位置)

var a = { x : 1 }
var b = a
a.x = a = { n : 1 }
console.log( a.x )  // undefined
console.log( b.x )  //{ n : 1 }
</script>

 

 

 

new做的四件事情?
      01 创建了一个新的对象
      02 new调用了这个构造函数
      03 改变了this的指向(让函数中的this指向这个新的对象)
      04 返回这个新的对象
 
 
什么是原型对象?
    原型对象指的是prototype,函数一旦创建出来,它就会有一个属性叫prototype。通过函数的.prototype属性可以找到自己的原型对象,每个函数都有自己的原型对象(除箭头函数以外,箭头函数没有原型对象,console.log( )输出箭头函数的原型对象,结果是undefined,箭头函数还没有this和arguments)。
 
什么是实例?
    一个对象是通过构造函数new出来的,这个对象就是这个构造函数的实例
    在js中,实例默认可以访问自己构造函数的原型对象中的方法  
 
原型对象有什么用?
    使用原型对象可以解决内存浪费和全局污染
               比如一些公用的方法,如果放到构造函数中,new一个实例就会创建一次方法,浪费内存,而放到原型中,无需创建就可以直接使用
    
 

 

 

对象查找属性的规则:

    先在自己身上找,如果有,直接使用 ,如果没有,顺着原型链往上找,找到了就使用,找不到就继续往上找,如果找到了Null都没有的话,就返回undefined;

 

 

 

 

 外部作用域不能访问内部作用域,内部作用域可以访问外部

查找变量,先在当前作用域查找,如果没有会沿着作用域链往上找

给变量赋值,访问的时候,要先找到变量

在代码执行前要先考虑预解析规则,函数里的代码执行前也要考虑预解析规则

查找变量,如果找到全局都没有会报错。

如果给变量赋值没有声明,找到全局都没有声明,会自动在全局创建这个变量

 

在js中函数会构成一个局部作用域。全局中有函数,全局的是0级链,全局中的函数时1级链,函数中如果有函数就是2级链,这样的关系就是作用域链。 

作用域链是由作用域串联而成的链式结构

 

什么是原型?

     原型指的是原型对象,prototype。函数创建出来的时候,对应产生一个对象,这个对象叫做原型对象。 除了箭头函数以外,所有函数都默认有原型对象,通过函数名.prototype的方式可以访问

 

原型对象prototype有什么作用?

    节约内存。比如构造函数中的方法,放到prototype中可以避免重复创建

          数组和对象  中的很多方法也是放到prototype中的,如果没有prototype,数组和对象的一堆方法,会很浪费内存。将数组和对象的方法放到各自的原型对象prototype中,数组和对象

的实例,就可以直接使用。(实例可以默认访问自己函数的原型对象,自己函数原型对象中的方法,可以直接使用)

          

 

 

原型对象的属性?

      原型对象中有一个  constructor 的属性, 指向自己的函数

      原型对象默认可以被自己的函数实例访问

什么是实例?

      通过构造函数new出来的对象就叫做实例

被构造函数new出来的实例可以通过._ _proto_ _ 来访问对应的原型对象

什么是原型链?

    实例---null构成的链式结构,由原型对象逐级继承 与 实例形成的链式结构  就是原型链

    原型链上保存着这个对象所有可用的方法

 

构造函数new出来的实例对象,查找规则?

    先在自己身上找,如果没有,沿着原型链往上找,如果找到null还没有,就返回undefined  

 

 

内置对象

var ary = new Array( );  // 说明 ary 是 Array的实例

通过new Array() 创建了一个新的对象ary。这个ary是Array的实例

var ary = [ ]    // 底层也是 new Array( ) 

结论:所有的数组都是Array的实例,因为所有的数组都是Array的实例,所以所有的数组都可以访问到Array的原型对象中的方法

 

 

 

 

 

 

  

  

<!-- 在原型对象中添加方法,简单写法 -->
   <!-- 在原型对象中添加方法,简单写法 -->
<script>
        
      function fn(){

      }
      fn.prototype = {
          constructor:fn, // 如果使用简单方式给原型添加方法,会丢失constructor,需要手动添加
          one : function(){
              console.log(1);
          },
          two : function(){
              console.log(2);
          },
          three : function(){
              console.log(3);
          }
      }

     var f =  new fn();
     f.one();
     f.two();
     f.three();
    
    
</script>

 

// instanceof 的作用:
// js基础:用于判断对象是某个函数的实例(用来判断对象的类型是谁)
// JS高级:判断一个函数的原型对象,是否在实例的原型链上,如果这个函数在实例的原型链上,那么返回true,否则返回false 
 
// 比如 : 
var ary = [] //new Array()
console.log( ary instanceof Array ); // true  // 判断 Array 函数的原型对象,是不是在ary实例的原型链上
console.log( ary instanceof Object ); // true

 

 

 

一个实例一旦创建出来,它的原型链就固定了,不会随着函数原型的改变而改变。这就是原型链的不可变

 

当我们需要自己调用函数,并且要修改函数中this的指向的时候,用 call / apply

当我们不需要自己调用函数,要浏览器帮我们调用(事件处理函数,定时器的回调函数),并且要修改函数中this的指向的时候,用bind。bind不会调用方法,会克隆

bind的注意点:

 function fn ( ) {

    console.log( this )

}

var f = fn.bind([1,2,3])

fn()  // [1,2,3]

 

为什么要学习继承?简单点说是为了少写代码

 

单个对象的继承

方法一: 单个对象的继承可以用: for key in xxx  和  对象.hasOwnProperty('属性名') //如果对象有这个属性就返回true,否则返回false

方法二

 单个对象继承,利用   var 新对象 = Object.create(被继承的对象)

新的对象.__proto__ == 被继承的对象
   <!-- 单个对象的继承 -->
<script>
      var zh = {
            name:'zh',
            age:18,
            money:9999999999999
      }

// 利用Object.create() 实现继承
      var zxh = Object.create(zh)
      zxh.name = 'zhx'
      console.log(zxh.age); // 18
      console.log(zxh)
</script>

 

 

 

 

 构造函数的继承(借用构造函数法)

   <!-- 构造函数的继承 -->
<script>
// 借用构造函数法实现
function Person(name,age) {
      this.name = name;
      this.age = age;
}
function Student(name,age,score) {
      Person.call(this,name,age)
      this.score = score
}
// Student里面的name和age不想再重复的书写了,借用构造函数法实现继承
var zh = new Student( 'zh',18,100)
console.log( zh )  // {name: "zh", age: 18, score: 100}
</script>

 

 

 

<!-- 构造函数的继承   原型继承-->
//  原型继承: 专门用来继承写在原型上的属性和方法
方法一 :Student.prototype = new Person();
方法二 :Student.prototype = Person.prototype;
   <!-- 构造函数的继承 -->
<script>
// 借用构造函数法实现
function Person(name,age) {
      this.name = name;
      this.age = age;
}
Person.prototype.say = function () {
      console.log( '你好,我是'+this.name );    
}
function Student(name,age,score) {
      Person.call(this,name,age) //借用构造函数继承,只能继承写在函数体内的this.xxx的属性
      this.score = score
}
//  如果想要继续原型上的属性和方法 ,那么就要使用原型继承这个方式
// 原型继承:专门用来继承写在原型上的属性和方法
Student.prototype = new Person()
var zh = new Student( 'zh',18,100)
console.log( zh.say()    )  // 你好,我是zh
</script>

 

 





 私有的属性写在构造函数中,公有的属性写在原型上

借用构造函数法用来继承私有属性,原型继承用来继承公有的属性

组合继承 = 解构构造函数继承 + 原型继承

 

Function自己创造了自己

Object是大写Function的实例

在js中,先有的Function函数,通过 new Function() 来创建对象。

 

 

javaScript是一门单线程的语言

    JS在工作的时候,一次只能做一件事,做完一件事, 才能去做下一件事情。这就是单线程语言

    java是多线程语言,一次可以做好几件事情

 

浏览器中的 渲染引擎: 渲染html+css

       js解析器:执行js代码

      v8引擎:google创建出来的,是js工作的平台,js是在v8引擎中工作的

 

 

堆和栈可以理解为内存中的一块区域

堆里面存储着很多数据,比如 声明的变量,声明的对象 都是存在堆里面的

堆:  变量,对象

 

基本数据类型存在栈里

引用数据类型存在堆里

 

js中,所有代码执行的时候,都会加载到栈中执行

事件轮询一直在观察栈和任务队列,如果栈空了,就会去任务队列中拿第一个出来,然后放到栈中执行

 

<script>
 
console.log( 1 );
setTimeout( function(){
      console.log( 2 );  
},0 )
console.log( 3 );
// 输出 1 3 2 
/*
js所有代码执行的时候都会加载到栈中执行,如果有定时器/事件处理函数 不会立刻执行,定时器/事件处理函数会先在浏览器的webApi中暂时存储,
当时间到了或者事件被触发了,浏览器会把回调函数或者事件处理函数放到任务队列中排队。当栈里面的代码执行完毕了,事件轮询就会把任务队列中
的第一个拿到栈中执行, 执行完毕后,事件轮询还会去任务队列中拿下一个,再放到栈中执行。
*/
 
</script>

 

面向对象

 面向过程的思想:一步一步的具体去做这个事情

 面向对象的思想:需要哪个对象,调用这个对象的某个方法,帮助我们实现具体的需求

 面向对象是对面向过程的封装

 

 什么是面向对象?

    面向对象是一种编程思想,js本身就是基于面向对象构建出来的(例如:js中有很多内置类 ,像 promise就是ES6中新增的一个内置类,我们可以基于new Promise来创建一个实例,来管理异步编程),包括我们平时用的

Vue jq 等也是基于面向对象构建出来的,他们都是类,平时开发的时候都是创建他们的实例来操作的。

    js中的面向对象,和其它编程语言还是有略微不同的,js中类和实例是基于原型和原型链机制来处理的,而且js中关于类的重载 重写 继承和其它语言也不太一样  

 

 

arguments是函数中的一个对象,arguments是一个伪数组,里面存储了所有传进来的实参

 

继承:子类继承父类中的属性和方法(目的是让子类的实例能够调取父类中的属性和方法)

方案一:原型继承

    让父类中的属性和方法在子类实例的原型链上

    Son.prototyp =  new  Father( ) 

    Son.protoype.constructor =  Son

<!DOCTYPE html>
<html lang="en">
<head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
</head>
<body>
<script>
function Father (x) {
      this.x = x;
}
Father.prototype.getX = function () {
      console.log( this.x )
}


function Son (y) {
      this.y = y;
      Father.call(this,y)
}
Son.prototype = new Father(200)
Son.protoype.constructor =  Son // 保证原型重定向后的完整性
Son.prototype.getY = function () {
      console.log( this.y )
}

let son1 = new Son(100)
son1.y;
son1.getY();

</script> 
</body>
</html>

 

 

推荐阅读