js学习-day06

函数作用域

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <!-- 
        函数作用域
            调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
            每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
            在函数作用域中可以访问到全局作用域的变量
                在全局作用域中无法访问到函数作用域的变量
            当在函数作用域操作一个变量时,它会先在自身作用域中寻找
                如果有就直接使用
                如果没有则向上一级中个寻找,直到找到全局作用域
                如果全局作用域中依然没有找到,则会报错ReferenceError
            在函数中药访问全局变量可以使用window.对象的方法

     -->
 <script type="text/javascript">
     var a = "coco";
     function fun(){
         var a = "this is coco";
         console.log(a);//this is coco
         var b = "jelly";

         function fun2(){
             console.log(window.a);//coco
         }
     }
     //fun();
     console.log(a);//coco
     console.log(b);//undefined

     //在函数作用域也有声明提前的图形
     //    使用var关键字声明的变量,会在函数中所有代码执行之前被声明
     //    函数声明也会在函数中所有代码执行之前被声明
     function fun3(){
         console.log(a);
         var a = 5;

         fun4();
         function fun4(){
             console.log("i am fun4");//i am fun4
         }
     }
     fun3();

     var c = 33;
     function fun5(){
         console.log(c);//33
         // var c = 10;这个c是局部的,如果加了var会undefined
         c = 10;

         //d没有使用var关键字,则会设置为全局变量
         window.d = 555;
     }
     fun5();
     console.log(c);//10
     console.log(d);//全局输出的变量555

     //定义形参就相当于在函数作用域中声明了变量
     var e = 333;
     function fun6(){
         alert(e);//333
     }
     fun6();
 </script>
</body>
</html>

 

一个需要注意的地方↓↓↓

上面的那个alert还是会报错undefined,而不是456

执行结果如下

 形参有用的情况  123 456

 

 和下面这个不同  执行结果123 456

 

this

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<!-- 
    解析器在调用函数时每次都会向函数内部传递进一个隐含的参数
        这个隐含的参数就是this,this指向的是一个对象
        这个对象我们称为函数执行的上下文对象
        根据函数的调用方式的不同,this会指向不同的对象
            1.以函数形式调用时,this永远都是window  fun()
            2.以方法的形式调用时,this就是调用方法的那个对象

    以函数形式调用就是window对象调用,函数就是window的方法,跟alert一样
 -->
 <script type="text/javascript">
     function fun(a,b){
         //console.log(a+b);
         console.log(this.name);//Object Window
     }
     fun(123,456);

     var obj = {
         name:"coco",
         sayName:fun
     };
     var name = "全局的name属性"; //这样调用fun()时的this就是全局变量里的window

     //console.log(obj.sayName == fun);//true
     //obj.sayName();//object  --obj

     //以函数形式调用,this就是window
     fun();//window
 </script>
</body>
</html>

 

用工厂方法批量创建对象

 

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7     <!-- 
 8         使用工厂方法创建对象
 9             通过该方法可以大批量创建对象
10 
11         使用工厂方法创建的对象,使用的构造函数都是object
12             所以创建的对象都是Object这个类型
13             就导致我们无法区分出多种不同类型的对象
14      -->
15 <script type="text/javascript">
16     var obj ={
17         name :"coco",
18         sayName:function(){
19             alert(this.name);
20         }
21     };    
22 
23     obj.sayName();
24 
25     //设置形参才能在声明对象的时候自定义对象的属性
26     function createPerson(name,age){
27         //创建一个新对象
28         var obj = new Object();
29         //向对象中添加属性
30         // obj.name  = "coco";
31         // obj.age = 21;
32 
33         //用形参之后
34         obj.name = name;
35         obj.age = age;
36 
37         obj.sayName = function (){
38             alert(this.name);
39         };
40         //将新的对象返回
41         return obj;
42     };
43 
44     //创建新的对象
45     var obj2 = createPerson();
46     var obj3 = createPerson();
47     console.log(obj2);
48     console.log(obj3);
49 
50     //用了形参之后
51     var obj4 = createPerson("lisa",22);
52     var obj5 = createPerson("happy",32);
53     console.log(obj4);
54     console.log(obj5);
55 </script>
56 
57 <script type="text/javascript">
58     function createDog(name,age){
59         var obj = new Object();
60         obj.name = name;
61         obj.age = age;
62         obj.sayHello = function(){
63             alert("wangwang");
64         };
65         return obj;
66     }
67 
68     var dog = createDog("baibai",3);
69     dog.sayHello();
70 </script>
71 </body>
72 </html>

 

 

构造函数

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7     <!-- 
 8         创建一个构造函数,专门用来创建Person对象的
 9             构造函数就是一个普通的函数,创建方式和普通函数没有区别,
10             不同的是构造函数习惯上首字母大写
11         
12         构造函数和普通函数的区别就是调用方式的不同
13             普通函数就是直接调用,而构造函数需要使用new关键字来调用
14 
15         构造函数的执行流程
16             1.立刻创建一个新的对象
17             2.将新建的对象设置为函数中的this,
18               在构造函数中可以使用this来引用新建的对象
19             3.逐行知心函数中的代码
20             4.将新建的对象作为返回值返回
21 
22         使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数
23         称为一个类。我们将通过一个构造函数创建的对象,称为是该类的实例
24 
25 
26         使用instanceof可以检查一个对象是否是一个类的实例
27             语法 对象instanceof 构造函数
28             是的话返回true
29         所有的对象都是Object的后代,所以任何对象
30         和Object做instanceof检查是都会返回true
31 
32         this的情况
33             1.当以函数的形式调用时,this是window
34             2.当以方法的形式调用时,谁调用方法this就是谁
35             3.当以构造函数的形式调用时,this就是新创建的那个对象                            
36      -->
37 <script type="text/javascript">
38     function Person(name,age){
39         alert(this);//object object
40         //alert("hello");
41         this.name = name;
42         this.age = age;
43         this.sayName = function(){
44             alert(this.name);
45         };
46     }
47     var per = new Person("star",11);
48     console.log(per);//hello
49 
50     function Dog(name,age){
51         alert(this);//object object
52         //alert("hello");
53         this.name = name;
54         this.age = age;
55         this.sayHello = function(){
56             alert(this.name);
57         };
58     }
59     var dog = new Dog("xiaobai",2);
60     console.log(dog);//hello
61 
62 
63     //使用instanceof可以检查一个对象是否是一个类的实例
64         //语法 对象instanceof 构造函数
65         //是的话返回true
66     console.log(per instanceof Person);//tu
67     console.log(per instanceof Object);
68 
69 </script>
70 </body>
71 </html>

 

执行结果可以区分Person和Dog,这就是构造函数设置的目的,这样能够更好地区分

 

 多态函数,可以共享一个方法

解决方法:将函数提出,然后在构造函数里面调用

 

 

原型(这个有点不清楚,然后自己去找了文档)

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7 <!-- 
 8     原型prototype
 9         我们创建的每一个函数,解析器都会向函数中添加一个属性prototype
10             这个属性对应着一个对象,这个对象就是我们所谓的原型对象
11         如果函数作为普通函数调用prototype没有任何作用
12         当函数通过构造函数形式调用时,它所创建的对象中都会有一个隐含的属性,
13         指向该构造函数的原型对象,我们可以通过_proto_来访问该属性
14 
15         原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到
16         这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中
17 
18         当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则
19         直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
20 
21         以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法
22  -->
23 
24  <script type="text/javascript">
25      function Person(){
26 
27      }
28 
29      var per = new Person();
30      var per2 = new Person();
31      //console.log(Person.prototype);//object object
32 
33      //指向该构造函数的原型对象,用_proto_来访问该属性
34      console.log(per._proto_);//object object
35      console.log(per._proto_ == Person.prototype);//true
36 
37      //
38      per.a = "我是per中的a";
39      console.log(per.a);
40      console.log(per2.a);
41 
42      //向Person的原型中添加属性a
43      Person.prototype.a = 123;
44      //向Person的原型中添加一个方法
45      Person.prototype.sayHello = function(){
46          alert("hello");
47      }
48 
49 
50      //将函数定义在全局作用域,污染了全局作用域的命名空间
51      //而且定义在全局作用域中也很不安全
52      function fun(){
53          alert("hello我是"+this.name);
54      };
55      //向原型中添加sayName方法
56      Person.prototype.sayName = function(){
57          alert("hello呀"+this.name);
58      };
59 
60      var per = new Person("coco");
61  </script>
62 </body>
63 </html>

 

 文档解释的原型对象

https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/Object_prototypes

1.先创建一个fun函数,然后显示出他的原型对象,两种形式都可以显示出函数的原型对象

<script type="text/javascript">
    function fun(){}
    console.log(fun.prototype);//会有一个默认的prototype
    var fun = function(){};
    console.log(fun.prototype);
</script>

会出现一个_proto_对象

 

2.向函数添加原型对象

//添加属性到fun1的原型上面
    function fun1(){}
    fun1.prototype.foo = "bar";
    console.log(fun1.prototype);

 

 3.在原函数的基础上,再添加属性

//可以使用new运算符在这个原型的基础上,创建一个fun1的
//实例。在调用函数时,在函数名的前面加上一个new,就会返回
//一个这个函数的实例化对象
    var obj = new fun1();
    obj.prop = "money";
    console.log(obj);   

 会有原来的函数的属性,然后自己刚刚添加的属性

 

4.理解原型对象

function Person(first, last, age, gender, interests) {
  
  // 属性与方法定义
  
};
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
person1.valueOf();

在 JavaScript 控制台输入 "person1.",你会看到,浏览器将根据这个对象的可用的成员名称进行自动补全。

原型链

 

person1.valueOf()

这个方法仅仅返回了被调用对象的值。在这个例子中发生了如下过程:

  • 浏览器首先检查,person1 对象是否具有可用的 valueOf() 方法。
  • 如果没有,则浏览器检查 person1 对象的原型对象(即 Person构造函数的prototype属性所指向的对象)是否具有可用的 valueof() 方法。
  • 如果也没有,则浏览器检查 Person() 构造函数的prototype属性所指向的对象的原型对象(即 Object构造函数的prototype属性所指向的对象)是否具有可用的 valueOf() 方法。这里有这个方法,于是该方法被调用。

 

posted @ 2019-07-13 15:27  进击的小laufen  阅读(229)  评论(0编辑  收藏  举报