JS笔记3.2--函数成员/函数的apply/call/bind/sort/toString方法/this指向/闭包/垃圾回收

apply和call:改变this指向

    //apply和call的使用方法
    /*
    * apply的使用语法:参数以数组的形式传递
    * 函数名或方法名.apply(对象,[参数1,参数2,...]);
    * call的使用语法:参数以枚举的形式传递
    * 函数名或方法名.call(对象,参数1,参数2,...);
    * 想要使用其他对象的某个方法:其他对象.方法名.apply(当前对象,参数,...);
    * 这个方法就会被当前的对象所使用,同时这个方法中的this就是当前的对象,在调用方法的时候改变了this的指向
    * 作用:改变this的指向
    * 不同的地方:参数传递的方式是不一样的
    *
    * 只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用apply或者是call的方法改变this的指向
    *
    * 实例对象调用方法,方法要么在实例对象中存在,要么在原型对象中存在
    * */
    function f1() {
      console.log(this);
    }
    //f1是函数,f1也是对象
    f1.apply();
    f1.call();    //对象调用方法,说明该对象中有这个方法
    console.log(f1.__proto__==Function.prototype);
    //所有的函数都是Function的实例对象
    console.log(Function.prototype);//ƒ () { [native code] }
    //apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype中
#call() & apply()
<script type="text/javascript">
	/*
	* call()和apply()方法:
	*   这两个方法都是函数对象的方法,需要通过函数调用来实现
	*   当对函数调用call()和apply()方法时,都会调用函数执行
	*  在调用call()和apply()方法时,可以将一个对象设置为第一个参数
	*   此时,这个对象会成为函数调用时的this
	*  call()方法可以将实参在对象后依次传递
	*  apply()方法需要将实参封装到一个数组中统一传递
	* 
	*  this:
	*  1.以函数的形式调用时,this永远都是window
	*  2.以方法的形式调用时,this永远是调用方法的对象
	*  3.以构造函数的方式调用时,this是新创建的对象
	*  4.使用call和apply调用时,this是指定的那个对象
	*/
        function fun()
	{
		console.log(this.name);
	}
        var obj1 = {
		name:"obj1的name"
	}
	var obj2 = {
		name:"obj2的name"
	}
	fun.call(obj1);// obj1的name
	fun.apply(obj2);// obj2的name
	
	function fun2(a,b)
	{
		console.log("a="+a);
		console.log("b="+b);
	}
	fun2.call(obj1,1,2);
	fun2.apply(obj2,[1,2]);
	//输出 a=1,b=2
</script>

bind:复制并改变this指向

bind方法:复制,参数可以在复制的时候传,也可以在复制之后的调用时传。
语法:函数名或方法名.bind(对象,参数1,参数2,…); //返回值是复制之后的这个方法或函数

			//函数使用bind方法,null表示this指向window
			function f1(x,y){
				console.log(x,y)
			}
			var ff = f1.bind(null)//将函数f1复制给ff,同时this指向window
			ff(1,2)
			//方法使用bind,改变this指向
			function Person(age){
				this.age = age
			}
			Person.prototype.play = function(){
				console.log(this+this.age)
			}
			function Student(age){
				this.age = age
			}
			var per = new Person(1)
			var stu = new Student(2)
			var pp = per.play.bind(stu)//把per的play方法复制给pp,同时将this指向stu对象
			pp()

函数成员

name属性—>函数名,name属性是只读的,不能修改
arguments属性—>实参的个数
length属性—>函数定义的时候形参的个数
caller属性—>调用者

函数作为参数使用

函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号

			function f1(fn){
				fn();//参数作为函数调用
			}
			//传入匿名函数
			f1(function(){
				console.log('我是匿名函数')
			});
			function f2(){
				console.log('我是命名函数')
			}
			f1(f2)//传入命名函数,只传函数名

获取某个对象的数据类型:

Object.prototype.toString.call(对象);

			var arr=[10,20,30];
			console.log(Object.prototype.toString.call(arr));//[object Array]
			console.log(Object.prototype.toString.call(new Date()));//[object Date]

使用sort方法对数组进行排序

匿名函数作为sort方法的参数使用

            var arr = ["acdef","abcd","bcedf","bced"];
			arr.sort(function(a,b){
				if(a>b){
					return -1;
				}else if(a==b){
					return 0;
				}else{
					return 1;
				}
			})
			console.log(arr);//["bcedf", "bced", "acdef", "abcd"]

JS中作用域

在一对大括号中定义的变量,是全局变量。
在函数中定义的变量,是局部变量。
只有定义新的函数,才会开启新的作用域。

this:普通函数/方法和es6中箭头函数中this指向的区别

在普通函数/方法中,谁调用this就指向谁

<script type="text/javascript">
		/*
		* this对象
		* 解析器在调用函数时,每次都会向函数内部传递一个隐含的参数this
		* 根据函数调用方式的不同,this会指向不同的对象
		* 1. 以函数的方式调用时,this永远都是window
		* 2. 以方法的形式调用时,this就是调用方法的对象
		* 3. 构造函数中的this 和 原型对象中方法的this 都是指向 实例对象
		*/ 
	        function fun1()
		{
			console.log(this);
		}
		fun1();  //输出是 window
		
		var obj = {
			name:"孙悟空",
			sayHello : fun1
		}
		obj.sayHello(); //输出是 Object {name: "孙悟空"}
</script>

this.属性名 指向当前对象的属性
<script type="text/javascript">
	    var name;
	    function fun1()
		{
			console.log(this.name);
		}
		fun1();  //输出是 window
		
		var obj = {
			name:"孙悟空",
			sayHello : fun1
		}
		
		var obj2 = {
			name:"猪八戒",
			sayHello : fun1
		}
		obj.sayHello(); //输出是 孙悟空
		obj2.sayHello(); //输出是 猪八戒
</script>

在箭头函数中的this,是父作用域中的this,不是调用者

    <script>
        let p = {
            name:'jiaody',
            say:function(){
                console.log(this)
            },
            hi:()=>{
                console.log(this)
            }//此时箭头函数没有定义在其他函数中,所以此时箭头函数属于全局作用域。this指向window
        }
        p.say();//{name: "jiaody", say: ƒ, hi: ƒ}
        p.hi();//Window
    </script>
    <script>
        function  Person() {
            this.name = 'jiaody';
            this.say = function () {
                console.log(this)
            };
            this.hi = () =>{
                console.log(this)
            }//此时箭头函数定义在构造函数中,所以箭头函数属于构造函数。由于箭头函数的this始终指向其父函数
            //所以此时箭头函数中的this就是构造函数中的this
        }
        var p = new Person();
        p.say();//Person {name: "jiaody", say: ƒ, hi: ƒ}
        p.hi();//Person {name: "jiaody", say: ƒ, hi: ƒ}
    </script>

闭包

		//闭包:函数A中,有一个函数B,函数B中可以访问函数A中定义的变量或者是数据
		//函数形式的闭包:在一个函数中有函数
		//如果想要缓存数据,就把这个数据放在外层的函数和里层的函数的中间位置
		function f1(){
			var num = 10;
			return function(){
				return num;
			}
		}
		var f2 = f1()
		var result = f2()
		console.log(result)//10
		
		//对象形式的闭包:在一个函数中有对象
		function func(){
			var num = 100;
			return {
				score:num
			}
		}
		var obj = func()
		console.log(obj.score)//100

//普通的函数
function f1() {
  var num = 10;
  num++;
  return num;
}
console.log(f1());//11
console.log(f1());//11
console.log(f1());//11

//函数模式的闭包
function f2() {
  var num = 10;
  return function () {
    num++;
    return num;
  }
}
var ff = f2();
console.log(ff());//11
console.log(ff());//12
console.log(ff());//13

垃圾回收

     /*
    * 垃圾回收机制GC
    * 垃圾:当一个对象没有任何的变量或属性对其进行引用,再也无法对其进行引用,此对象就是垃圾
    * 这种对象过多,会占用大量的内存空间,导致程序运行变慢,必须进行垃圾清理
    * 垃圾回收机制,会自动将垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收操作。
    * 将不再使用的对象设置为null,即可。
    */ 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值