• web概述14


    数组

    数组长度可变,索引值可以从0开始,但是事实上也可以使用负数,所以 javascript 中数组的实现实际上是采用hash表

    • 同一个数组中的元素类型可以互不相同,也允许相同,但是下标不允许相同,如果相同则后盖前
    • 访问数组元素不会产生越界问题,访问未赋值元素时返undefined。一般建议使用for/in结构访问
    <script>
    var arr = [1, 2, 3, 4, 5, 6];
    // for (let k = 1; k <= arr.length; k++) {
    // // console.log(arr[-k]);
    // document.writeln(arr[-k] + "
    ");
    // } //下标可以使用负数,但是一般不建议 arr[-1]=99; arr[9]=100; alert(arr.length); //如果一旦使用负数下标则arr.length不是元素个数,而是最大下标 +1 console.log(arr); //实际存储为[1, 2, 3, 4, 5, 6, -1: 99] for(let k=-5; k<arr.length;k++){ document.writeln(arr[k]+"
    "
    ); } document.writeln("
    "
    ); for(let k in arr){ //for/in结构类似于foreach document.writeln("arr["+k+"]="+arr[k]+"
    "
    ); } </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    多维数组:数组的元素还是数组

    多维数组:数组的元素还是数组
    
    • 1
    数组中的常见方法

    concat(arr1,arr2,…)用于连接两个或者多个数组,参数可以是具体的值,也可以是数组对象

    <script>
    var arr=[1,2,3,4];
    arr=arr.concat(12); //可以拼接具体的数据
    for(let k=0;k<arr.length;k++){
    document.writeln(arr[k]); //1 2 3 4 12
    }
    document.writeln("
    "
    ); var brr=[[2,3],[4,5,6],[7]]; arr=arr.concat(brr,34,56); for(let k=0;k<arr.length;k++){ document.writeln(arr[k]+"
    "
    ); } </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • join(分隔符)用于将数组中的所有元素连接称为一个字符串,分隔符可选,如果不设置的默认使用逗号,各个元素之间使用分隔符分开
    <script>
    var arr=[1,2,3,4,[5,6]];
    var ss=arr.join();
    document.writeln(ss+"
    "
    ); //1,2,3,4,5,6 ss=arr.join("---"); document.writeln(ss+"
    "
    ); //1---2---3---4---5,6 </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • pop()用于删除并返回数组中的最后一个元素
    • push()向数组的末尾添加一个或者多个元素,并返回新长度
    • shift()用于将数组的第一个元素删除,并返回第一个数组元素的值
    • unshift()向数组头部添加一个或多个元素,并返回新长度

    使用数组模拟实现一个栈和队列

    • reverse()数组反转,颠倒顺序
    <script>
    var arr=[];
    alert(arr.push(123));
    arr.push("萌新开");
    arr.push(new Date());
    arr.reverse(); //原地反转操作
    for(let k in arr)
    document.writeln("arr["+k+"]="+arr[k]+"
    "
    ); </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • slice()从数组中获取指定下标范围的数组元素
    <script>
    var arr=[];
    for(let i=0;i<10;i++){
    arr[i]=parseInt(Math.random()*100); //将浮点数强转为整型
    }
    document.writeln(arr.join()+"
    "
    ); //slice用于获取数组的子数组,参数1是起始下标,参数2为终止下标,含左不含右。如 果不指定终止下标,则到数组结束 var brr=arr.slice(1,4); document.writeln(brr.join("===")+"
    "
    ); var crr=arr.slice(6); document.writeln(crr.join(">>")); </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • sort()对数组中的元素进行排序,允许自定义排序规则
    <script>
    var arr=[];
    for(let i=0;i<10;i++){
    arr[i]=parseInt(Math.random()*100);
    }
    //使用sort针对数组中的元素进行排序
    arr.sort(); //如果不指定比较规则,则使用默认的字典序从小到大排序
    document.writeln(arr.join()+"
    "
    ); //允许自定义排序规则,sort方法的参数就是元素的比较函数 arr.sort(function(a,b){ return b-a; }); document.writeln(arr.join()+"
    "
    ); </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • splice(index,number,item1,item2,…) 可以从数组中添加删除元素,返回被删除的元素
      • index必须的,整数,规定添加、删除元素的位置,使用负数则表示从数组结尾处规定位置
      • number必须的,要删除的元素数量,如果值为0则不会删除元素
    <script>
    var arr = [];
    for (let i = 0; i < 10; i++) {
    arr[i] = parseInt(Math.random() * 100);
    }
    document.writeln(arr.join("::")+"
    "
    ); var brr=arr.splice(2,3);//从下标2开始删除3个元素,brr中存储的就是删除的3个 元素 document.writeln(brr.join("::")+"
    "
    ); document.writeln(arr.join("::")+"
    "
    ); document.writeln("
    "
    ); var crr=arr.splice(1,0,12,34,56); document.writeln(crr.join("::")+"
    "
    ); document.writeln(arr.join("::")+"
    "
    ); </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    函数

    函数是一段可以复用的代码,可以独立独立存在,可以当作一个类使用,同时函数也是一个对象,本身是Function实例

    函数定义方法

    方法1:命名函数

    function 函数名称(形参列表){代码块;}

    <script>
    //注意: js是弱类型编程语言,所以参数上没有类型,也没有返回值类型
    function sayHello(name){
    //修改
    中的显示内容 var div1=document.getElementById("div1"); div1.innerHTML="你好,"+name+"!"; //函数可以有返回值,也可以没有 return 100;//如果没有返回值,则没有【return 值】的语句,或者【return;】 } </script> <div id="div1">原始显示内容</div> <!-- 定义一个点击事件触发函数执行,函数不调用则不会执行。onclick属性值为调用函数的语句 -- > <button onclick="sayHello('yanjun')">点击</button>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    方法2:匿名函数 function(形参){代码块;} ,另外特殊的还有ES6提供的箭头函数

    <script>
    var f=function(name){
    var div1=document.getElementById("div1");
    div1.innerHTML='Hello '+name+"!";
    }
    </script>
    <div id="div1">原始显示内容</div>
    <button onclick="f('yanjun')">点击</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方法3:使用Function类定义匿名函数 var f=new Function(“形参列表”,“具体的代码块”)

    <script>
    var f=new Function("name", "var
    div1=document.getElementById('div1');div1.innerHTML='hello'+name+'!';")
    </script>
    <div id="div1">原始显示内容</div>
    <button onclick="f('yanjun')">点击</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三种方法的对比:

    • 函数声明有预解析,而且函数的声明优先级高于变量
    • 使用Function构造函数定义函数的方式是一个函数表达式,这种方式会导致两次解析,严重影响性
      能。第一次解析常规的JavaScript代码,第二次解析传入构造函数的字符串
    递归函数

    递归函数是一种允许在函数定义中调用自身函数的特殊函数。例如计算n的阶乘, n!=n*(n-1)!

    • 在js函数中允许在不同的情况下返回不同类型的数据,但是一般不建议这种写法
    var f=function(n){
    if(typeof(n)=='number'){
    if(n==1) return 1;
    else return n*f(n-1);
    }else
    alert('参数类型错误');
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用递归调用计算n的阶乘

    <script>
    function jieCheng(num) {
    alert(num instanceof Number);
    //数据类型的判断可以使用typeof或instanceof两种方式判断
    if ((!(num instanceof Number)) || num < 1) {
    alert('参数错误!');
    return -1;//返回-1用于表示计算出现错误,当然也可以使用throw new
    Error("")抛出异常
    }
    if (num == 1) return 1;
    else
    return num * jieCheng(new Number(num - 1));
    }
    // var res = jieCheng('5'); 报错 -1加上alert
    var res=jieCheng(new Number('5'));
    alert(res);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    数据类型判断instanceof不正确,除非new Number(5),否则instanceof为false

    <script>
    function jieCheng(num) {
    if (!(typeof(num)=='number') || num < 1) {
    alert('参数错误!');
    return -1;//返回-1用于表示计算出现错误,当然也可以使用throw new
    Error("")抛出异常
    }
    if (num == 1) return 1;
    else
    return num * jieCheng(num - 1);
    }
    // var res = jieCheng('5'); 报错 -1加上alert
    var res=jieCheng(5);
    alert(res);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    编写JS的流程

    • 布局:html+css 在写js之前必须保证有一个稳固的布局,这个布局本身不能有任何兼容问题
    • 属性:确定要修改哪些属性 确定通过js修改哪些属性,例如display
    • 事件:确定用户做哪些操作(产品设计)确定要在什么样的事件里修改,比如点击、移入移出
    • 编写js:在事件中,用js来修改页面元素的样式
    btn1.style.display='block' 将btn1的style的display的值设置为block
    get Element By Id 通过id获取元素
    <label onmouseover = “document.getElementById(‘btn1’).style.display=‘block’”
    onmouseout = “document.getElementById(‘btn1’) .style.display=‘none’“>鼠标经过出
    现按钮</label>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    局部的概念

    在函数中定义的变量就是局部变量,仅仅在函数内部范围内有效,特殊问题就是提升问题。

    <script>
    function ff(){
    var kk=99;
    document.writeln("在ff函数内部调用kk="+kk+"
    "
    ); } //首先先调用函数。函数不会主动执行 ff(); document.writeln("在函数外部访问函数内的kk="+kk+"
    "
    ); //Uncaught ReferenceError: kk is not defined </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在函数外部定义的变量就是全局变量

    • 局部变量只能在函数内部访问,全局变量可以在所有的函数里访问
    • 局部变量在函数执行完毕后销毁,全局变量在页面关闭后销毁。
      注意:在函数内没有使用var定义的变量也是全局变量
    <script>
    var kk=99;
    function ff(){
    // kk=100;
    document.writeln("在ff函数内部调用kk="+kk+"
    "
    ); } ff(); document.writeln("在函数外部访问函数内的kk="+kk+"
    "
    ); </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    局部函数是在函数内部定义的函数,例如在outer函数中定义一个函数inner,则inner就是局部函数,outer则是全局函数。可以在outer函数内访问inner局部函数,但是在outer函数之外则无法访问内部局部函数inner

    <script>
    function outer(){
    function inner(){
    document.writeln("局部函数111
    "
    ); } document.writeln("开始测试局部函数...
    "
    ); inner(); //调用内部局部函数 document.writeln("结束测试局部函数....") } outer();//调用外部函数 // 在外部函数之外不能调用内部函数,只能通过外部函数调用内部函数执行 inner(); //试图调用局部内部函数,内部函数.html:15 Uncaught ReferenceError: inner is not defined </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    非要在外部函数之外访问内部函数的解决方案:

    <script>
    function ff(){
    var kk=100;//在ff函数内部有效,局部变量
    function show(){ //内部函数,一般外部函数之外不能直接访问
    alert("内部函数中访问内部局部变量:"+kk);
    }
    // show();
    return show; //返回内部函数,从而将show挂在到window对象上
    }
    var p=ff(); //接收ff函数的返回值,从而将p挂在到window对象
    p();//实际上就是调用ff的内部函数show()
    //ff();
    //show();
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    闭包[面试]

    闭包就是能够读取其它函数内部变量的函数,是将函数内部和函数连接起来的一个桥梁,即使外部函数已经执行完毕。

    JavaScript 自带了垃圾回收机制,对于函数而言,在函数执行完毕后会被垃圾回收机制回收,进行内存释放,函数内部的局部变量也会被销毁,在内存中仅仅只能保存全局作用域

    <script>
    function ff(){
    var kk=100;//局部变量,仅仅在ff的范围内有效
    }
    ff();
    document.writeln(kk); //如果访问内部布局变量,则Uncaught ReferenceError: kk
    is not defined
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    为了在外部直接访问函数内部的变量或者直接调用内部的函数,可以引入闭包以延长内部变量的有效范围

    <script>
    function ff(){
    var kk=100;//局部变量,仅仅在ff的范围内有效
    return kk;
    }
    var p=ff();
    document.writeln(p);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    引入闭包的原因

    • 使得外部得以访问函数内部的变量
    • 避免全局变量的使用,防止全局变量污染
    • 让关键变量得以常驻内存,免于被回收销毁

    针对内部函数

    <script>
    function ff(){
    function show(){}
    return show;
    }
    var p=ff();
    p();
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    闭包的验证

    function f1(){
    var num=999;
    add=function(){
    num++;
    }
    function f2(){
    alert(num);
    }
    return f2;
    }
    var res=f1();
    add();//注意add由于没有使用var定义,所以add属于全局的
    res();
    add();
    res();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意点:

    • 由于闭包会使得函数中的变量被保存到内存中,内存消耗会比较大,所以具体使用中注意不要滥用
      闭包。解决方案是:在推出函数之前,将不再使用的局部变量删除
    • 闭包会在父函数外部改变父函数内部变量的值。会影响代码的封装性

    全局和局部冲突

    var sex=true;
    function ff(){
    console.log("ff before:"+sex);
    var sex=123;
    console.log("ff end:"+sex);
    }
    ff();
    alert(sex);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    自定义类
    张老太养了两只猫猫:一只名字叫小白,今年3岁,白色;还有一只叫小花,今年10岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字、年龄和颜色。如果用户输入的小猫名错误,则显示”张老太没有这只猫猫“。

    用现有的技术来解决

    var cat1Name="小白";
    var cat1age=3;
    var cat1Color="白色";
    var cat2Name="小花";
    var cat2age=10;
    var cat2Color="花色";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    用面向对象技术来解决张老太养猫问题

    //定义猫对象
    function Cat(){ }
    //定义主人
    function Master(){ }
    var master1=new Master();
    master1.mName="张老太";
    //实例化猫
    var cat1=new Cat();
    //!!特别说明: 在js中,你给它什么成员属性,是自由的.
    cat1.cname="小白";
    cat1.age=3;
    cat1.color="白色";
    cat1.master=master1;
    var cat2=new Cat();
    cat2.dname="小花";
    cat2.age=100;
    cat2.color="花色";
    //访问一下
    document.write(cat1.cname+" "+cat1["cname"]+" 它的主人是"+cat1.master["mName"]
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    访问对象公开属性的方式有两种:

    • 对象名.属性名
    • 对象名[‘属性名’]
      类(原型对象)和对象(实例)的区别和联系
    • 类(原型对象)是抽象的,概念的,代表一类事物,比如人、猫…
    • 对象是具体的,实际的,代表一个具体事物
    • 类(原型对象)是对象实例的模板,对象实例是类的一个个体
      对象的属性
      对象的属性,一般是基本数据类型(数、字符串),也可是另外的对象。比如前面创建猫对象的age就是猫对象的属性
      this的用法
      使用this关键字修饰的变量不再是局部变量,它是该函数的实例属性
    function Person(name,age){
    this.name=name; //实例对象每个实例都不同,可以通过new Person("",19).name的方式访
    问
    Person.nation="汉族"; //类属性,是类的所有实例公用,只能通过Person.nation的方式访
    问,而不能使用new Person("yan",18).nation方式访问
    var bb=0;//局部变量,外面不能访问,类似局部函数
    cc=123;//全局变量
    this.show=function(){} //public的成员方法
    Person.bbb=function(){} //类成员
    abc=function(){} //全局方法
    }
    //注意:局部变量在函数执行完毕后销毁,全局变量在页面关闭后销毁,函数内没有使用var声明的变量
    (需要通过this.的方式)为全局变量
    //直接定义一个对象
    var p={
    pp:function(){
    for(var k=0;k<10;k++)
    document.writeln("慢慢的走...");
    }
    }
    //调用方式
    p.pp();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    js是一种动态语言,允许随时给对象增加属性和方法,直接为对象的某个属性赋值时就是给对象增加属性。

    var obj={}; //使用JSON语法创建一个对象
    obj.name='zhangsan'; //向obj对象中添加一个属性name
    obj.show=function(){}; //向obj对象中添加一个成员方法show
    
    • 1
    • 2
    • 3

    总结:函数、方法、对象、类
    JavaScript中函数定义后可以得到4项内容

    • 函数:函数和 Java 中的方法一样,这个函数可以被调用。没有形参和实参一一对应的问题
    <script>
    var f = function (name, age) {
    alert(name + "-->" + age);
    //可以通过arguments获取所有请求参数
    for(let kk in arguments){
    document.writeln('参数['+kk+"]="+arguments[kk]+"
    "
    ); } } f('yanjun',18,23); //实参只有一个,但是形参有2个,实际上传值是从左向右对 应,如果缺少则默认传值为undefined </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 对象:定义一个函数,系统也会创建一个对象,这个对象就是Function类的实例
    var f=function(){}
    alert(f instanceof Function);// true 表示f就是Function类型的变量,可以通过f()
    调用函数
    alert(f instanceof Object);// true,表示f是Object类型的变量
    alert(f instanceof String);//false,表示f不是String类型
    
    • 1
    • 2
    • 3
    • 4
    • 5

    针对对象,如果需要了解核心细节,可以使用console.log(f)输出/console.info

    • 方法:定义一个函数时,这个函数通常会被附加给某个对象,作为对象的方法。如果没有明确指出将函数俯角到哪个对象上,该函数则将附加到window对象上,作为window对象的方法
    var f=function(){}
    console.log(window);
    window.f();
    f();
    
    • 1
    • 2
    • 3
    • 4
    • 类:定义函数时也得到一个与函数同名的类,该函数就是该类的唯一的构造器。所以实际上函数有
      直接调用和使用new关键字调用两种方法
    var f=function(){
    alert('hello javascript!');
    }
    //直接调用f();
    //使用new运算符创建对象时,会自动执行function()中的定义,function()会当作类的构造器
    var ff=new f();
    alert(ff);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    调用函数的4种方法

    方法1:作为一个函数调用,基础语法【函数名(实参列表)】。函数实际上作为全局对象调用,会使this的值成为全局对象,使用window对象作为一个变量,容易造成程序崩溃

    <script>
    function bb(){
    this.name="zhangsan";//实际上是将name定义为全局属性
    console.log(this); //输出的应该是window对象
    }
    bb();
    window.bb();
    document.writeln("window.name="+window.name); //证明name称为全局属性
    document.writeln("name="+name);//实际输出和window.name一致
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方法2:函数作为方法调用。函数作为对象的方法进行调用,会是this的值称为对象本身

    //使用JSON格式定义对象,JSON的语法格式为{key1:value1,key2:value2...}
    var p1={
    "username":"zhangsan", //定义属性,格式为【属性名:值】
    "age":18,
    show:function(k){//定义方法,格式为【方法名称:function(形参){}】
    console.log(this);
    document.writeln(k+"---"+this.username+"---"+this.age);
    }
    };
    //通过对象名.方法名的形式调用show函数
    p1.show(12);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    方法3:使用构造器的方式调用函数,构造函数中的this指向当前对象

    function Person(){
    this.name="zhangsan";//定义public属性
    this.age;
    this.show=function(){
    console.log(this);
    document.writeln("name:"+this.name+",age:"+this.age);
    }
    }
    var p1=new Person(); //则function Person()会自动调用执行
    alert(p1.name);//获取p1对象中的name属性值
    alert(window.name);//不能获取到数据,因为Person中的this用于指代Person类型对象,不是
    window对象
    p1.show();//调用成员方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    方法4:作为函数间接调用。实现有3种不同方式

    类和对象

    定义函数后实际上可以得到4项内容

    • 函数。可以直接调用
    • 对象。Function类型的实例
    • 方法。函数会自动附加到某个对象
    • 类。函数是类的唯一构造器
    //前面已经进行了试验
    function Person(name,age){
    this.name=name; //实例属性,每个实例都不一样,可以通过【对象名.属性名】的方式进行
    访问
    Person.nation="汉族"; //静态类属性,所有对象共享的属性,只能通过【类型名.属性名】
    的方式访问
    Person.show = function () { //静态类成员方法
    console.log(this); //this可以使用,用于指代当前函数
    console.log(this.username); //undefined
    console.log(this.nation); //汉族
    }
    var bb=100; //局部变量或者理解为私有属性,不能通过对象名的方式进行访问,可以使用闭
    包函数访问
    var ff=function(){
    return bb;
    }
    return ff;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    class关键字
    ES6引入了class关键字可以用于定义类,但是需要考虑浏览器的支持问题

    class Person{
    constructor(){ //定义构造器函数,只能定义一个,名称固定,参数个数没有限制。如果需
    要定义多个构造器可以考虑使用arguments判断参数格式
    if(arguments.length>1){
    this.username=arguments[0];// this用于定义公共属性
    this.age=arguments[1];
    } else if(arguments.length==1){
    this.username=arguments[0];
    this.age=99;
    } else {
    this.username="zhangsan";
    this.age=18;
    }
    }
    //可以定义成员方法,规则是【方法名称(参数列表){}】
    show(){
    return "Hello "+this.username+",今年"+this.age+"岁了!";
    }
    }
    var p=new Person();
    document.writeln(p.show());
    p=new Person("lisi",55,true); //按照处理逻辑并没有接收arguments[2],所以true没有
    使用
    document.writeln(p.show());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    函数间接调用的3种方式
    直接调用 p.pp(1,2,3);

    • call方法动态调用函数
    var ee=function(arr,fn){ //其中参数fn就是调用时才设置的函数
    for(var index in arr){
    fn.call(null,index,arr[index]); //调用函数fn,参数1调用的函数所属于的对象,
    如果值为null则表示window,后面参数则是调用函数时的参数
    }
    }
    //调用ee函数
    ee([2,3,4,5,6],function(index,ele){ //function()就是传递给fn的函数
    document.writeln("第"+index+"个元素是"+ele+"
    "
    ); });
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • apply动态调用函数

    通过call调用函数时必须在括号种详细列出每个参数,但是通过apply动态调用函数时,可以在括号中以arguments代表所有参数

    var ff=function(a,b){
    alert(a+b);
    }
    ff.call(window,12,23); //12和23对应的就是函数中的参数,通过call方法动态调用时需要为每
    个调用方法逐个的传入参数,写法为12,23
    ff.apply(window,[12,23,34,56]);//通过apply方法动态调用方法时,能与arguments一次性传
    入多个参数,例如这里的参数就是一个数组[12,23,34,56]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    函数的参数处理
    JavaScript 采用值传递方式,当通过实参调用函数时,传入函数里的不是实参本身,而是实参的副本,因为在函数中修改参数值并不会对实参有任何影响。复合类型参数的是一个引用

    <meta charset="UTF-8">
    <script>
    function ff(person) {
    if (typeof (person) == 'object') {
    person.age = 100;
    } else alert('参数类型不是复合类型' + typeof person);
    }
    person={"age":99,toString:function(){return "age:"+this.age}};
    ff(person);
    document.writeln(person);
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    参数的新问题
    在 JavaScript 中没有函数重载的概念,函数名称是函数的唯一标识,如果定义两个同名函数,则后盖前

    function ff(person){
    if(typeof(person)=='object'){
    person.age=100;
    } else
    alert('参数类型不是复合类型'+typeof person);
    }
    ff(); //person形参对应的实参为undefined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    原型

    JavaScript 是基于原型的语言,原型可以理解为原件,通过精确地复制原件可以创建对象。JavaScript对象都有一个叫做原型的公共属性,这个原型属性就是构造函数的原型对象prototype。

    function Person(){
    this.name="Nicholas";
    this.age=29;
    this.job="Software Engineer";
    this.sayName=function(){}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

  • 相关阅读:
    解锁Spring组件扫描的新视角
    你清楚AI、数据库与计算机体系
    计算机毕业设计Java我图你秀图片素材交易平台(源码+系统+mysql数据库+Lw文档)
    JavaEE-网络编程-客户端服务器
    <script>标签内容详解
    SmartNews 基于 Flink 的 Iceberg 实时数据湖实践
    CSS-注册页面
    精准定位——MySQL日志学习的一天【错误、二进制、查询、慢查询】
    【SpringBoot高级篇】SpringBoot: 事件的发布和监听
    与HTTP相关的各种协议
  • 原文地址:https://blog.csdn.net/weixin_44251806/article/details/127793997