关于Javascript的一些理解

1.拷贝

     1.1浅拷贝

      首先我们来看下面一段代码段:

	var obj1 = {
		name: 'HHH',
        age: 20,
        sex: '男',
        dog: {
        name: '金毛',
        age: 2,
        yellow: '黄色'
        }
    }
	var obj2= {};
	//封装函数 将o1中的成员复制给o2
	function copy(o1, o2) {  
		for (var key in o1) {
			o2[key] = o1[key];
			}
        }
	//调用函数
	copy(obj1, obj2);
	//修改obj1中的成员
	obj1.name = 'pgone';
	obj1.dog.name = '阿毛';
	//打印obj2的属性
	 console.dir(obj2);

      在上面这段函数中,我们创建一个obj1的对象,然后封装一个拷贝函数,在obj1中我们再创建一个dog属性对象,再赋给他一些属性。在封装函数调用之后,自然拷贝成功obj2,此时obj2的属性和obj1完全一样。在调用之后,修改父对象中的成员,发现它自身的属性无法修改,而子对象(属性)中的属性可以修改。这是什么原因呢?下面利用一张对象关系图进行解析。

在这里插入图片描述
      obj1中增加了一个dog的属性,所以在内存中开辟了一个新的内存空间来存储dog属性,并且obj1中的dog指向dog的内存地址。当我们拷贝了一个同样的obj2对象,它的dog属性仍然指向同一个内存地址,但是在内存中并没有复制一个dog对象,所以指向同一个dog对象,所以导致以上结果。这称为浅拷贝。

     1.2深拷贝

      利用上面同样的案例,我们附加一些属性。之前可以浅显理解为浅拷贝只是复制了对象的一层。那么深拷贝,顾名思义,则可以多层复制。

var obj1 = {
	name: 'HHH',
	age: 20,
	sex: '男',
	dog: {
		name: '金毛',
		age: 2,
		yellow: '黄色'
		},
	friends: ['K9999', 'baebae']
	}
var obj2= {};
//封装函数 深拷贝将o1中的成员复制给o2
function deepCopy(o1, o2) {
	for (var key in o1) {
	//获取key属性对应的值
	var item = o1[key];
	//如果item是对象?
	if (item instanceof Object) {
		o2[key] = {};
		deepCopy(item, o2[key]);
		} else if (item instanceof Array) {
			//如果item是数组?
			o2[key] = [];
			deepCopy(item, o2[key]);
			}  else {
				//如果是简单类型
				o2[key] = o1[key];
                }                
            }
        }
	deepCopy(obj1, obj2);
	//修改obj1中的成员,是否会影响obj2?
	obj1.dog.name = '阿毛';
	obj1.friends[0] = 'AR';
	//查看obj2的属性
	console.dir(obj2);

       这时,我们打印结果发现obj2的属性中的子对象属性并没有被改变,我们继续从内存中去看问题。
在这里插入图片描述
       利用递归的代码进行深拷贝,不同于浅拷贝的是,需要考虑对象中的子对象的问题。这时经过代码判定item对象和Array对象之后进行深拷贝,在内存中也创建了对应的自己的内存,此时改变obj1的属性则不会改变obj2中的属性。

2.JS的闭包

       闭包是一个概念,不同的人对于其解释不同,这里我们查看MDN上的解释:函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在JavaScript,函数在每次创建时生成闭包。
       我们简化一下就是:闭包是一个函数,是一个可以访问独立数据的函数。
       下面我们看一段代码段:

var name = 'PGONE';
var object = {
    name: 'My Object',
    getNameFunc: function () { 
    	var that = this; 
        return function () {  
            return that.name;
        };
    }
};
console.log(object.getNameFunc()());

       这里我们最后调用的位置就是全局作用域。首先调用getNameFunc返回一个函数function,第一处调用是object来调用,此是this指向object,所以that记录了object对象,所以第二次调用的时候返回that.name那么就是’My Object’。这里是否发生闭包了?在一个作用域中访问了另一个作用域的变量,确实发生了闭包。

3.遍历DOM树

       下面一段代码:

function loadTree(parent, callback) {  
    for (var i = 0; i < parent.children.length; i++) {
        //遍历第一级别子元素
        var child = parent.children[i];
        if(callback) {
            //处理找到的子元素
            callback(child);
        }
        //递归调用
        loadTree(child);
    }
}

var ul = document.getElementById('list');
loadTree(ul, function (element) {
    element.onclick = function () {
        console.log(this.innerText);
    }
});

       这里递归调用了body中的所有子元素。实际开发中我们需要将这些元素注册事件。可以通过回调函数不断回调从而不断遍历。我们通过获取元素之后就可以对其进行函数来注册事件。这对于实际的工作中是有用的。

4.正则表达式

       正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法。
       需要记住的是,RegExp对象中test()为匹配方法,exec()提取方法但是只提取一个内容。
       String对象中,match()也为提取,可以提取多个内容,如下代码:

var str1 = '[email protected], [email protected] 这是其他内容 [email protected] 2、[email protected] [email protected]...'; 
var reg = /\w+@\w+(\.\w+)+/g;
console.log(str1.match(reg));

       replace()替换方法,可以利用正则表达式str.replace(/\s/g, ‘’)或者下面的split()方法+join的拼接方式进行删除替换内容。代码如下:

var str = '   123AD  asdsadsa     adf'    ;
console.log(str.replace(' ', ''));
console.log(str.replace(/\s/g, ''));
console.log(str.split(' ').join(''));

       上面内容中,不使用g(global)即在正则表达式后面加全局变量的话,提取出来的只有第一个内容,也就是内容不全,这里值得注意。


附录一些常用的正则表达式特殊字符和元字符:

元字符 说明
\d 匹配数字
\D 匹配任意非数字的字符
\w 匹配字母或数字或下划线
\W 匹配任意不是字母,数字,下划线
\s 匹配任意空白字符
\S 匹配任意不是空白符的字符
. 匹配除换行符以外的任意单个字符
^ 匹配行首的文本(以此开始)
$ 匹配行尾的文本(以此结束)

限定符 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n次到m次

其它特殊字符 说明
[] 表示匹配任一字符相当于或的意思
[^] 匹配除中括号以外的内容
\ 转义符
| 或者,选择两者中的一个
() 从两个直接量中选一个,分组
发布了2 篇原创文章 · 获赞 1 · 访问量 239

猜你喜欢

转载自blog.csdn.net/AllEyezOnMewas/article/details/104433675