js1---函数(this-new关键字)

162 阅读6分钟

函数

函数对任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。在javascript里,函数即对象,程序可以随意操控它们。函数可以嵌套在其他函数中定义,这样它们就可以访问它们被定义时所处的作用域中的任何变量,它给javascript带来了非常强劲的编程能力。

1 函数概述

– 一处定义,处处调用;

– 如果把函数作为一个对象的属性,则称为方法;

– 每次调用函数会产生一个this:谁调用这个函数或者方法,this就指向谁;

– 函数就是对象,可以给他设置属性或方法;

2 函数定义的三种方式

1)声明式 function fn() {代码}

2)定义式 var obj={name:"zs",fn:function(){}} var arr=[1,2,function fn(){}]

3)构造函数 var re=new Function("parameters","执行的代码")

4)案列 判断闰年 :

    function getLeapYear(year) {
        var a1=(year%4==0)&&(year%100!=0);
        var a2=(year%100==0)&&(year%400==0);
        if(a1||a2){
            return "闰年"
        }
        return "平年"
        
    }
    var re=getLeapYear(2022)
    console.log(re);
    var re1=getLeapYear(2000)
    console.log(re1);

3 函数的调用

函数的调用 最后一定会生成一个结果 函数没有返回值的话 调用结果为undefined

    function fn(){

    }
    var re=fn();
    console.log(re);

    写返回值 就是返回数据
    function tool(){
        return 100;

   };//return一旦运行 函数体后来无论还有多少代码 都不会运行了 直接生成函数结果
   var re=tool();
   console.log(re);

4 return关键字

不写return或者return紧跟着的后面不写代码的话就是一个空表达式 会生成结果undefined,函数不一定要写返回值,函数调用后一定有返回值。

    function fn(a) {
        // return;(
        //     a+20
        // )
        return(
            a+20
        );
        
    }
    
    var re=fn(100)
    console.log(re);
    
    

image.png

5 变量的作用域(入门)

5.1

1)在es5中 函数的代码块内部的代码 可以访问形参变量 也可以访问外部的变量(全局) 就近优先

2)函数外面的代码不能直接访问函数内部的变量

3)作用域: 指一个变量它在哪些代码范围能够被使用,这些地方就是变量的作用域

4)只有函数才有作用域的说法,对象没有这个说法

5.2 全局变量

变量会在程序运行时 把它设置为window对象的属性

                    var a=20
		function fn(){
			a=40
		}
		fn()
		console.log(a)
                    

image.png

5.3 局部变量

局部变量就是函数内部能使用 外部不能使用的变量( var,形参)

                    var a=20
		function fn(a) {
			var b = 20
			console.log(a, b)
		}
		fn(100)

		console.log(a)
                    

image.png

1)案列1

                     var obj={
			name:"karen"
		}
		function fn(n){
			//隐式代码: var n="karen"
			n="jack"
		}
		fn(obj.name)//obj.name取值然后再传入函数
		console.log(obj.name)
                    

image.png

2)案列2

             var obj={
			name:"karen"
		}
		function fn(n){	
			//隐式操作 var n=内存中的数那个传入的对象
			// n.name="jack"  其实没有修改n的值
			n={name:"jack"}//把n的值改了
		}
		fn(obj)//obj取值操作 取的是一个引用的对象
		console.log(obj.name)
                    

image.png

6 this关键字

6.1 this官方解释

this(this代表的是 执行这个this代码的环境对象)

this基本上就代表的是对象 在及其少的时候 this不是对象(call apply bind)

6.2 详解

1)this在脚本中代表的是window的全局对象

    console.log(this);

2)this在全局函数中代表的是window的全局对象

      function fn666() {
        console.log(this);
        
    }
    fn666();

3)var a=20 全局变量会在脚本执行时 把变量名设置为全局对象window的属性

4)function fn() {console.log(this);}全局函数会在脚本执行时 吧函数设置为全局对象window的方法

6.3 常见情况

1)this关键字代表了函数调用时的调用者

    function fn() {
        console.log(this);
    }
    fn()//这个代码不是fn在调用 fn代表一个函数 是window在调用
    

2)匿名函数 自调用 调用者全局变量window

    (function () {
        console.log(this);
    })();

3)特殊

    function fn() {
        return function fm() {
            console.log(this);
        }
        
    }
    fn()()//window

6.4 函数嵌套

在js程序中无论多么复杂的程序 this只需要看离最近(嵌套)的function的这个单词的调用者

                            var obj={
			name:"karen",
			say:function(){
				console.log(this)//obj
				function fn(a){
					console.log(a,this)//obj winodw
				}
				// var a=this
				// fn(a)
				fn(this)//fn(obj)
			}
		} 
		 obj.say()//obj

image.png

6.5 调用者常见情况总结

fn()// window

obj.fn() //obj

obj.xx.xx2()//obj.xx

(function(){})() window

fn()() window

fn()[1] () // fn()返回的数组

6.7 面试题

1)

            var name = 'lili';
		var obj = {
			name: 'liming',
			prop: {
				    name: 'ivan',
				    getname: function() {
					return this.name;
				    }
			      }
		};
		console.log(obj.prop.getname());
		var test = obj.prop.getname;
		console.log(test());
       obj.xxxx
       

image.png

分析

1.obj.prop.getname() 访问到prop的getname成员并调用,调用者为prop,因此this指向prop,返回值为name成员,打印“ivan”

2.var test = obj.prop.getname;这行代码表示将getname成员取出来,console.log(test());表示调用getname函数,此时的调用者为window,打印“lili”

2)

                      function Foo() {
		     getName = function () {console.log (1);}; 
		     return this;
		    }
                       var  getName = function  () {console.log (4);};
			
			 Foo()
			 Foo().getName ()
                             

image.png

分析

1.Foo()调用函数,window是调用者,将getName = function () {console.log (4);};改为getName = function () {console.log (1);};

2.Foo().getName ()=window.getName () 打印“1”

7 形参与实参

实际传入函数的参数(实参) 的个数可以比形参的个数多,按照顺序赋值,不会影响程序的执行逻辑但是会影响性能

实际传入函数的参数(实参) 的个数可以比形参的个数少,按照顺序赋值,可能会影响程序的执行逻辑

        function fn(a,b,c){
        c=a+b;
         console.log(c);
       }
         fn(10,20,30);

fn(a,b,c)为形参, fn(10,20,30)为实参

7.1 函数的length属性

函数的length属性代表的是形参的个数

用法:console.log(fn.length)

7.2函数的arguments属性

arguments,代表实际传入函数的参数列表(类数组)

用法:

console.log(arguments)

console.log(arguments.length)//实参个数

7.3函数的name属性

name代表函数的名称,函数的名称一般都为自己的函数名

用法:console.log(fn.name)//fn

8 new关键字

new fn() new关键字后面跟函数 是一个表达式(运算符) 创建对象的运算 整个表达式一定会得到一个对象

8.1 new使用时的步骤

1).创建一个空对象==> 创建一个空对象{} 给它添加一个属性 proto 这个属性引用fn.prototye

2). 运行构造函数,让内部的this指向创建的对象(用创建的空对象去调用构造函数)

3). 整个表达式的结果看函数的返回值:返回值是引用数据 那么就是返回值,返回值不是引用数据 那么就是这个运行完毕之后的创建的那个对象

8.2 this-new综合案列分析

      function Parent() {
        this.a = 1; 
        this.b = [1, 2, this.a]; 
        this.c = {
            demo: 5
        };
        this.show = function() {
            console.log(this.a, this.b, this.c.demo);
        }
        this.change = function() {
                                this.a = this.b.length;
                                this.c.demo = this.a++;
                            }
         return {
              show:function(){console.log(1,2,3)},
              change:function(){console.log(1,2,3)}
         }//"hello"					
    }
    var parent = new Parent();
    // var parent={a:4,b:[1,2,1],c:{demo:3},show:func,change:func}
                
    parent.change();
                
    parent.show();//4 [1,2,1]  3
   

分析: var parent = new Parent();构建一个空对象{proto:{}},添加成员var parent={a:4,b:[1,2,1],c:{demo:3},show:func,change:func}

parent.change();调用parent对象中的change成员 a=3,demo=3,a=4

parent.show();调用parent对象中的show成员 a=4,b=[1,2,1],c.demo=3