学习【JavaScript权威指南】(二)

第八章 函数

闭包:function fun(){  var x = 0; }   外部是不能访问函数内部的局部变量的,因为函数一调用,局部变量就会被释放,这该怎么呢?   换个想法,因为  在函数内部 是能访问 外部的变量的, 于是乎: 在 函数 内部 再定义 一个函数,并使用该变量:

function f1(){
   var x = 100;  //局部变量
   function f2(){
      console.log(x++); //在函数内部再定义一个函数
   }
   return f2;  //返回该函数
}
//调用,本来是 调用完 f1 就会销毁,但是现在 f2被赋给了全局变量 f,这导致f2一直在内存中,
//所以 f2不能被销毁,又因为 f2需要用到f1,所以f1也不能销毁。
var f = f1(); 
f();   //结果 100
f();   //结果 101
f();   //结果 102

//也就是说,  调用了 f1() 之后,x变量并没有被 回收!

关于闭包:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html  (最后的思考题我还是答错了哈哈哈哈)

主要是两点:1,外部访问局部变量   2,保存到内存中,不会被释放。

 

//定义函数
function fun(){ ... }
var fun1 = function(){  ... }
var fun2 = function fun(){ ... }

//函数定义后可以直接执行
var value = (function(x){return x*x;}(10));   //结果100

//如果没有 return 语句,函数返回的是 undefined

//当方法不需要返回值时,最好返回this,这样就可以使用“方法链”:
shap.setX("x轴").setY("y轴")

//创建对象,没有形参的可以省略括号
var o = new Object();
var o = new Object;

function fun(a) {
    if(a === undefined) a = [];
    //可以写成如下形式:
    //运算符 || ,第一个参数为真值得话就返回,否则返回第二个参数
    a = a || [];
}

//callee 调用自身
var factorial = function(x){
    if(x <= 1) return 1;
    return x * arguments.callee(x-1);
};

//函数可以作为 对象的 属性
var o = { square: function(x){ return x*x;}};
var y = o.square(2);    // 结果4

//甚至可以放到数组中
var a = [function(x){return x*x}, 2];
a[0](a[1]);    //结果4

不在任何函数内声明的变量都是“全局变量”,在整个JavaScript程序中都是可见的,避免污染全局命名空间。

function mymodeule(){ //定义

}
mymodule();  //调用

//可以直接写个 匿名函数,并立即在单个表达式中调用它:
//注意这里的左括号是必须的,如此才不会将关键字function解析为函数声明语句,使用圆括号才会正确的将其解释为函数定义表达式
(function(){

}());

当 函数,含有嵌套函数时:

JavaScript函数的执行用到了“作用域链”,这个作用域链是“函数定义的时候创建的”。

闭包的特性:  它们可以捕捉到 局部变量/参数,并一直保存下来。

函数定义时的作用域链,函数执行时依然有效

function counter(){
   var n = 0;
   return {
      count: function(){return n++;},
      reset: function(){ n = 0; }
   };
}

var c = counter();
c.count();    //0
c.count();    //1
c.reset();    //重置
c.count();    //0
c.count();    //1

利用闭包实现的私有属性取值方法:

   function addpro(o,name,predicate){
        var value;
        o["get"+name] = function () {
            return value;
        };
        o["set"+name] = function (v) {
            if(predicate && !(predicate(v))){
                throw Error("set"+name+": invalid value " + v);
            }else{
                value = v;
            }
        }
    }

   //调用
   $(function () {
        var o = {};
        addpro(o,"Name",function (x) { return typeof x == "string"; });
        o.setName("why_su");
        console.log(o.getName());   //结果why_us
        o.setName(0);   //抛出异常 setName: invalid value 0
    });

错误:

    function fun1(){
        var arrs = [];
        for(var i = 0; i < 10; i++){
            arrs[i] = function(){
                return i;
            }
        }
        return arrs;
    }

//调用
var arrs = fun1();
console.log(arrs[5]());   //10,并不是5

//上面代码创建了 10个闭包,这些闭包都是在同一个函数调用中定义的,所以可以共享变量i,
//当fun1()返回时候,变量i的值是 10,所有的闭包都共享这一个值

8.8节看不懂。。。。

 

第九章  类

//构造函数
function Person(username){
   this.username = username;
}
//构造函数加载完以后,会自动为构造函数生成一个对应的 原型对象
//Person构造函数有个属性prototype, 它指向的是 Person的原型对象
//也就是有两个对象, 一个是构造函数创建的对象,一个是原型对象
//将age, toString 保存在 原型对象中
Person.prototype.age = 24;
Person.prototype.toString = function () {
   return "username:"+this.username+",age:"+this.age;
};

//创建的 实例, 指向了该原型对象。(也就是该构造函数所指向的原型对象)
var p1 = new Person("whysu");
var p2 = new Person("top");
console.log(p1.toString());    //username:whysu,age:24
console.log(p2.toString());    //username:top,age:24

//原型对象 有个属性 constructor 【反向指回】这个构造函数
console.log(Person.prototype.constructor); //结果 f Person(username){this.username=username;}
console.log(p1.constructor); //在p1实例上找不到constructor方法,就向该创建了该实例的构造函数所指向的原型查找有没有改方法,
//结果 f Person(username){this.username=username;}

看书看的头晕,找了篇视频,一点就通。。

两种写法的区别:

//这种写法是【覆盖,重置】原型对象
//因为原型对象默认会有一个属性constructor,如果这里不写的话,该属性就没有了
Person.prototype = {
   constructor: Person,  //需要显示设置构造函数反向引用
   age: 24,
   toString: function(){
      return "username:"+this.username+",age:"+this.age;
   }
}

//这种写法是在原有基础上【添加】,所以constructor没被覆盖
Person.prototype.age = 24;
Person.prototype.toString = function(){
   return "username:"+this.username+",age:"+this.age;
}

构造函数初始化 后,js会自动为该构造函数 生成  原型对象, 那它是怎么生成的呢?  用的是:  

Person.prototype =  new Object();     也就是生成了一个Object对象。

 

鸭式辩型:像鸭子一样走路、游泳并且嘎嘎叫的鸟就是鸭子。。
不要关注“对象的类是什么”,而是关注“对象能做什么”~

 

第9章看不懂。。。太多文字。。不理解。。

 

 

第10章 正则表达式

两种方式:  var re = new RegExp("\d");   或两个斜杠 var re = /\d/;

[ ... ]  方括号内任意字符   [^ ... ] 不在方括号内任意字符

任意字符(除了换行符)

\w  等价于[a-zA-Z0-9]      \W 等价于  [^a-zA-Z0-9]

\d 等价于[0-9]     \D  等价于 [^0-9]

\s 任意空白字符,   \S 任意非空白字符

\b  代表着单词的开头或结尾,也就是单词的分界处,如果要搜寻 hi 这个单词的话,得用 \bhi\b,这样就不会搜寻类似him history这样的“包含”hi的单词

{n,m} 至少出现n次,最多m次    {n,}  出现n次 或多次    {n} 出现n次   

?   0次或一次       + 一次或多次      0次或多次

 匹配字符串的开头,多行检索中匹配一行的开头

匹配字符串的结尾,多行检索中匹配一行的结尾

贪婪的, 总是找最长的匹配的串

        //得使用【行首 ^ 行尾 $ 】,/^  $/  表示【所有匹配】而不是【部分匹配】
        //例如:"-----123@qq.com---"也是【部分】符合的,但它不是合法的邮箱,
        //必须使用 /^ $/ 表示【所有匹配】规则才行
        var str4 = "123@qq.com";
        var re = /^\w+@[a-z0-9]+\.[a-z]+$/i;
        if(re.test(str4)){
            alert("合法邮箱格式");
        }else{
            alert("邮箱格式不正确");
        }

        //将html标签过滤掉,获取纯文本
        var str3 = "<h1>标题<span>666</span></h1><p>段落1</p>";
        var re3 = /<.+>/g;
        console.log(str3.replace(re3,""));  //结果 ""
        //为什么会这样呢?因为正则有个特性【贪婪】,它会寻找匹配规则的【最长的】字符串,
        //可以看见 <h1> </p> 左右< >是符合要求的
        //于是整个字符串都被过滤了。所以需要<> 中不能出现<>

        var re3_1 = /<[^<>]+>/g;
        console.log(str3.replace(re3_1,""));  //结果 "标题666段落1"

        //将字母a全部变为0
        var str2 = "asdasd aaajoijio  dsfa";
        var re2 = /a/g;
        alert(str2.replace(re2,0)); //结果0sd0sd 000joijio  dsf0


        //获得该字符串第一个数字
        var str1 = "adsf 2 34 567 8910 csaddasd";
        var re1 = /\d/; alert(str1.match(re1));  //结果 2

        var re1_1 = /\d/g; alert(str1.match(re1_1));  //结果 2,3,4,5,6,7,8,9,1,0

        var re1_2 = /\d{2}/g; alert(str1.match(re1_2));  //结果 34,56,89.10

        var re1_3 = /\d+/g; alert(str1.match(re1_3));  //结果 2,34,567,8910


        //第二个参数是option选项,i 表示忽略大小写
        var re = new RegExp("a","i"); //等价于var re = /a/i; 在斜杆后面加 i
        var str = "Abcdef";
        console.log(str.search(re));  //结果 0

|   或者           ( ... )  圆括号,分组,后面可以使用 \1 表示第1个分组,\3 表示第3个分组

(?:  ...)    圆括号,也是分组,但不可以用  \1 、\3来表示

零宽断言,预搜索: 类似\b 只是规定【位置】要遵循的规则,但不返回这些结果

(?= exp)   后面要遵循的规则,

(?<=exp)  前面要遵循的规则

(?! exp)   后面不要遵循的规则

(?<! exp)  前面不要遵循的规则

 

“str”.search(/\d/i);    返回索引,找不到就返回-1 ,不支持全局搜索(会忽略修饰符 g)

"str".replace(/\d\gi,"a");   

"str".match(/\d/g);   返回的是匹配的数组

"s-t-r".split("-");   按 - 拆分

"str".exec(/\d/);     exec和match方法一样是返回匹配数组,但exec返回的信息更加详细

 

第11章 JavaScript的子集和扩展

const 定义常量

const pi = 3.14;  //定义常量
pi = 4;  //任何对该常量【重新赋值】都会被忽略
const pi = 4;  //重新声明常量会报错   
var pi = 4;  //报错

关键字 let 在 javascript1.7版本后才可用。

通过var 声明的变量在函数内部是可用的,而通过let声明的变量则只属于就近的花括号括起来的语句块。

解构赋值,索引对应的地方赋值

let [x,y] = [1,2]; //等价于 let x = 1,y = 2;
[x,y] = [y,x];  //交换两个变量的值
let [z,f] = [1]; // z = 1, y = undefined
[,x,,y] = [1,2,3,4];  //x = 2,y = 4;

11.4迭代,看的头晕,先跳过。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的纺织品企业财务管理系统,源码+数据库+毕业论文+视频演示 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升,也为了对纺织品企业财务信息进行更好的维护,纺织品企业财务管理系统的出现就变得水到渠成不可缺少。通过对纺织品企业财务管理系统的开发,不仅仅可以学以致用,让学到的知识变成成果出现,也强化了知识记忆,扩大了知识储备,是提升自我的一种很好的方法。通过具体的开发,对整个软件开发的过程熟练掌握,不论是前期的设计,还是后续的编码测试,都有了很深刻的认知。 纺织品企业财务管理系统通过MySQL数据库与Spring Boot框架进行开发,纺织品企业财务管理系统能够实现对财务人员,员工,收费信息,支出信息,薪资信息,留言信息,报销信息等信息的管理。 通过纺织品企业财务管理系统对相关信息的处理,让信息处理变的更加的系统,更加的规范,这是一个必然的结果。已经处理好的信息,不管是用来查找,还是分析,在效率上都会成倍的提高,让计算机变得更加符合生产需要,变成人们不可缺少的一种信息处理工具,实现了绿色办公,节省社会资源,为环境保护也做了力所能及的贡献。 关键字:纺织品企业财务管理系统,薪资信息,报销信息;SpringBoot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值