javascript 学习笔记(2)

这篇博客探讨了JavaScript中的核心概念,包括函数的赋值、重载问题、隐式原型、函数作为参数传递,以及call和apply的使用。同时,讲解了对象创建、原型链的重写和注意事项,强调了解耦合和动态语言特性的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. js中控制html元素的样式以及普通事件的使用
<script type="text/javascript">
    function over(obj) {
        obj.style.color = "#f00";
        //在css中的以"_"连接的数据,在js中使用驼峰格式
        obj.style.fontSize = "20px";
    }
    function out(obj) {
        obj.style.color = "#000";
    }
    function clic(obj) {
        //获取的数据类型默认为String类型.
        var size = obj.style.fontSize;
        //parseInt() 函数可解析一个字符串,并返回一个整数。
        if(parseInt(size)) {
            obj.style.fontSize = parseInt(size) +2 +"px";
        } else {
            obj.style.fontSize = "16px";
        }
    }
</script>
</head>
<body>
<div onmouseover="over(this)" onmouseout="out(this)" onclick="clic(this)">啊啊</div>
</body>
  1. settimeout() setinterval().clearinterval()函数的使用
<script type="text/javascript">
    window.onload= function() {
        //此方法是只调用一次就结束
        setTimeout("cd()",3000);
        //会间隔1000秒定时执行
        timeId = setInterval("cd()",1000);
    }
    function stop() {
        //会将定时任务停止
        clearInterval(timeId);
    }
    function cd() {
        var abc = document.getElementById("abc");
        abc.style.fontSize = "100px";
    }
</script>
</head>
<body>
<div id="abc">啊啊</div>
</body>
  1. 实现js代码与html页面解耦和
<script type="text/javascript">
        window.onload=function() {
            var chen = document.getElementById("chen");
            chen.onclick=function(event) {
                //javascript会默认将event事件函数当做对象传递近来.
                //可是 event在其他浏览器中支持的程度不一样.所以
                // ||短路效果.如果false,则将后方的值给其赋值
                event = event || window.event;
                alert(event.type)
                alert(chen.textContent); 
            }
        }
    </script>
</head>
<body>
    <hr>
    <h3 id="chen"></h3>
    <hr>
</body>

js函数 间的赋值

<script type="text/javascript">

    function a() {
        alert("a");
    }
    var b = a;
    b();
    a = function() {
        alert("其他");
    }
    a();
    b();
    //function在内存中是通过键值对的形式保存的
    //此处是将a的方法的地址值与b进行关联
    //函数的赋值与对象的赋值是不同的.
    //函数赋值 : 是将方法拷贝给其,进行储存的 如 Function
    //对象赋值 : 是将该对象的引用给其保存的. 如 new Object()对象
</script>

js的函数重载问题

<title>函数重载</title>
<script type="text/javascript">
    function sum(num1,num2) {
        return num1+num2;
    }
    function sum(num1) {
        return num1 +100;
    }
    sum(10);
    sum(10,20);
    //结果均为110;
    //给以上方法换种定义方式
    var sum = function(num1,num2) {
        return num1+num2;   
    }
    var sum = function(num1) {
        return num1+100;
    }
    //由此可见,sum的方法是被最后定义的function决定的.
    //js中,函数就是对象,不存在重载.
    // 可以将函数理解为对象,因为函数可以当做参数,或者返回值进行传递.
</script>
</head>

js 隐式原型

<script type="text/javascript">
    // prototype 指向本对象.
    // js的隐式原型 prototype
    function Fn() {
        Fn.prototype.name = 100;
        Fn.prototype.age = function() {
            return 20;
        }
    }

    var fn = new Fn();
    //调用属性值为值
    alert(fn.name);
    //调用属性值为函数
    alert(fn.age());
</script>

js函数当做参数传递的使用

以 js 的 Array对象的sort方法为例

<script type="text/javascript">
    var arr = [ 1, 2, 4, 66, 44, 643, 343 ];
    //定义一个用于比较数据值大小的函数
    function sortByInt(a, b) {
        return a - b;
    }
    //将此函数当做参数传递进去,用作自定义的比较器
    arr.sort(sortByInt);
    alert(arr);
</script>
</head>

js动态语言的精简 以及 闭包的调用

<title>js动态语言的优势</title>
<script type="text/javascript">
    /**
        以对象和数字数组排序为例子. 展示动态语言的优势.这是java等强类型语言锁不具有的
    */
    //var arr = [1,34243,5454,65464,43,456];

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    var p1 = new Person("a",3);
    var p2 = new Person("b",2);
    var p3 = new Person("c",1);

    var arr = [p1,p2,p3];
    //debugger;
    //name比较器
    function sortByName(obj1,obj2) {
        if(obj1.name > obj2.name) return 1;
        else if (obj1.name == obj2.name) return 0;
        else return -1;
    }
    //age 比较器
    function sortByAge(obj1,obj2) {
        return obj1.age - obj2.age;
    }
    //精简后
    //其中,使用了闭包,内部函数调用父属性
    function sortByProperty(proper) {
        var sort = function(obj1,obj2) {
            if(obj1[proper] > obj2[proper]) return 1;
            else if(obj1[proper] == obj2[proper]) return 0;
            else return -1;
        }
        return sort;
    }
    //arr.sort(sortByAge);

    //调用
    arr.sort(sortByProperty("name"));
    alert(arr);

    for(var i =0;i <arr.length;i++) {
        alert(arr[i].name + " : " +arr[i].age);
    }
    /* arr.sort(sortByProperty("age"));
    alert(arr); */
</script>

js 函数的内部属性 –argumentgs 以及 this的使用

<script type="text/javascript">
    function arg(num) {
        //每个函数对象其内都有一个用来接收保存形参的属性 : arguments
        alert(arguments.length);
    }
    //arg(1,2,3,4);

    //求阶乘
    //阶乘的算法,集中在return 后 与调用函数的组合处的运算,因为调用函数返回的是一个数据
    function jc(num) {
        if(num <= 1) return 1;
        //else return num*jc(num-1);
        //此时,如果函数名被修改了,那么程序会报错.
        //为了实现函数内部的解耦,可以通过arguments.callee(num);此方法会调用其所在的函数.
        else return num*arguments.callee(num-1);
    }
    alert(jc(3));

    //this关键字  代表调用函数的当前对象.此时需要看函数上下文.
</script>

js的函数属性 call 与 apply的使用

<title>函数的属性 length 与 call和apply</title>
<script type="text/javascript">
    function arg(a,b,c) {
    }
    //函数的属性-lenght : 表示该函数期待接收的参数的数量/与函数内部属性的区别,该属性是通过函数名来调用的
    alert(arg.length);

    //函数的属性apply与call
    //两者的第一个参数都是函数的上下文对象,后者是方法的参数.
    //不同的是 apply的是数组形式,可以传递arguments
    //call,的参数则是单个的形参列表的形式. 均是对该函数的调用.

    //其上下文对象中: 最大的是window对象,其他则是各种函数对象.
</script>

js对象的创建以及json对象的创建

<title>js对象的创建</title>
    <script type="text/javascript">
        //js中没有类的概念,只有对象.因此少了类的约束,在js中对象不能实现复用
        //并且没有约定,在操作时会带来问题
        var obj = new Object();
        obj.name = "cai";
        obj.age = 23;
        obj.say = function() {
            //调用属性需要传入其上下文对象: 如 this等.指明范围
            alert(this.name + " : " + this.age);
        }
        //因为此处的say得内存原型是一个函数.所以,需要需要调用该函数,需要在键后加 ()
        obj.say();
        //以上创建对象的方式比较麻烦.所以使用json的方式创建对象
        //json也是js的对象

        //使用json创建对象
        var person = {
            name:"cai",
            age : 23,
            say : function() {
                alert(this.name + " : " + this.age);
            }
        };
        //使用json创建数组对象
        var pers = [
            {name : "cai",age : 23},
            {name : "changmeng",age : 23}
        ] 
    </script>
</head>

工厂模式创建对象以及函数构造方式创建对象

<title>工厂模式创建对象以及函数构造方式创建对象</title>
<script type="text/javascript">

    //工厂模式创建对象
    function createPerson(name,age) {
        var obj = new Object();
        obj.name = name;
        obj.age = age;
        return obj;
    }
    //此种方式:无法判断最终的对象是否是person对象.
    //因为
    var per = new createPerson("cai",23);
    alert(typeof per); // 为 Object类型

    //函数构造方式创建对象
    //该方式函数名首字母要大写,内部采用this来指定上下文
    function Person(name,age) {
        this.name=name;
        this.age=age;
        this.say=function() {
            alert(this.name + " : " + this.age);
        }
    }
    var per = new Person("cai",23);
    //此方法的好处,可以通过使用如下
    alert(per instanceof Person)
    //来判读该对象的类型
    //但是通过此方式创建对象,每次创建对象,都会拷贝其中对象内的函数属性给新的对象,占用内存空间
    //因此,可以创建全局函数,用其内部的函数属性指向该函数.实现复用
    //改进后 : 
    function say() {
        alert(this.name + " : " +this.age);
    }
    function PersonNew(name,age) {
        this.name=name;
        this.age=age;
        this.say=say;
    }
    var p1 = new PersonNew("cai",55);
    p1.say();
    //但是这种行为设置为全局的行为,会破坏对象的封装性
    //而且,如果某个对象有大量的方法,就会导致整个代码中充斥着大量的全局函数.
    //这样不利于开发.
</script>

 js的原型

这里写图片描述
这里写图片描述
这里写图片描述
体会 : 每一个根对象会有一个原型.通过该根对象创建的对象,内部都会有一个属性 _prop_ 来指定该根对象的原型.

<title>基于原型的对象创建</title>
<script type="text/javascript">
    function Person(){}
    Person.prototype = {
            //构造指向Person对象.
            constructor: Person,
            //在原型中添加属性
            name : "Leon",
            age:30,
            friends:["Ada","Chris"],
            say:function() {
                alert(this.name+"["+this.friends+"]");
            }
    }
    var p1 = new Person();
    p1.friends.push("chen yang");
    var p2 = new Person();
    p1.name="cai";
    p1.say();
    p2.say();
    //此种通过对象原型来封装对象,存在一些问题:
    // 1.无法通过构造函数设置属性值
    // 2.当属性中有引用类型变量时,可能存在变量值重复.某一个对象对原型操作后,其他对象也会一起变化.
    //因为 , 他们都是根据原型进行创建对象的.
    // 但是,可以在自己的对象内进行修改,保存在该对象的自身空间内.而不去是操作原型对象的属性
</script>
</head>

js 基于组合和动态原型创建对象的方式

<title>基于组合和动态原型创建对象</title>
<script type="text/javascript">
    function Person(name,age,friends) {
        this.name=name;
        this.age=age;
        this.friends=friends;
    }
    Person.prototype=function() {
        constructor:Person,
        say:function() {
            alert(this.name+"["+this.friends+"]");
        }
    }
    //组合和动态原型创建对象的好处:
    // 1.节省空间内存,不必每次创建对象均会拷贝行为给该对象
    // 2.能够通过初始化创建对象,指定该对象的内存空间中各自的属性,而且不必对原型空间进行操作

    //按照java的编码思想对其进行改造:
    function Person(name,age,friends) {
        this.name=name;
        this.age=age;
        this.friends=friends;
        //判断该对象原型是否是第一次初始化
        //如果say行为不存在,说明是第一次初始化
        if(!Person.prototype.say) {
            Person.prototype.say=function() {
                alert(this.name+"["+this.friends+"]");
            }
        }
    }
</script>

js的重写原型

<title>重写原型</title>
<script type="text/javascript">
    function Person() {
    }
    //以下定义太繁琐
    //如下方式为在原型中进行追加
    /* Person.prototype.name="cai";
    Person.prototype.age=12;
    Person.prototype.say=function() {
        alert(this.name+" : "+this.age);
    } */
    //可以通过json对象来简写,称为重写原型
    //由于原型重写,而且没有通过Person.prototype来指定
    //此时的constructor不会再指向Person 而是指向Object
    //如果constructor真的比较重要,可以在json中说明原型的指向
    //如下
    Person.prototype = {
        constructor: Person,//手动指定constructor
        name : "cai",
        age : 12,
        say : function() {
            alert(this.name + " : " + this.age);
        }
    }
    var p = new Person();
    p.say();
</script>

js对原型的重写的注意事项

// 重写后,之前原型内的所有属性均会被新原型所覆盖

<title>原型重写的问题</title>
<script type="text/javascript">
    // !每一个对象内,都有一个_prop_属性,指向其原型.
    function Person() {
    }
    //通过原型给该对象添加sayHi方法
    //原型1
    Person.prototype.sayHi=function() {
        alert(this.name + " : hi");
    }
    //此时创建一个对象
    var p1 = new Person();
    //此时该Person原型中并没有name 所以为undifined
    //并且此时p1对象的属性_prop指向原型1
    p1.sayHi();
    //对原型进行重写
    //此时是对原型进行了重写
    //原型2
    Person.prototype = {
        constructor: Person,
        name:"cai",
        age:12,
        say:function() {
            alert(this.name+" : "+this.age)
        }
    }
    var p2 = new Person();
    //报错,因为对原型重写后,原型内已经没有该方法了.
    //p2的属性_prop执行新的原型 _原型2
    p2.sayHi();
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值